From 8a3a3e7948f4345313b08c9b347d67265568d9ca Mon Sep 17 00:00:00 2001 From: nibbydev Date: Fri, 31 Mar 2023 12:02:50 +0300 Subject: [PATCH 01/21] DD4J-857 Fix timezone dependant test & fix heap memory issues in docker --- digidoc4j/pom.xml | 2 +- .../src/test/java/org/digidoc4j/SignatureTest.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/digidoc4j/pom.xml b/digidoc4j/pom.xml index 6d89455db..4cd4c40bb 100644 --- a/digidoc4j/pom.xml +++ b/digidoc4j/pom.xml @@ -495,7 +495,7 @@ org.apache.maven.plugins maven-surefire-plugin - -Dhttps.protocols=TLSv1.2 @{argLine} + -Xmx2048m -Dhttps.protocols=TLSv1.2 @{argLine} ${project.basedir}/src/main/lib/esteidtestcerts.jar diff --git a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java index 036306b2f..f940c583d 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java @@ -35,9 +35,13 @@ import java.security.cert.CertificateEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.Month; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; import java.util.Date; import java.util.List; -import java.util.Locale; public class SignatureTest extends AbstractTest { @@ -62,8 +66,11 @@ public void testGetSigningCertificateForBDoc() throws Exception { public void testTimeStampCreationTimeForBDoc() throws ParseException { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/test.asice"); Date timeStampCreationTime = container.getSignatures().get(0).getTimeStampCreationTime(); - SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d yyyy H:m:s", Locale.ENGLISH); - Assert.assertEquals(dateFormat.parse("Nov 17 2014 16:11:46"), timeStampCreationTime); + Date expectedDate = Date.from(OffsetDateTime.of( + LocalDate.of(2014, Month.NOVEMBER, 17), + LocalTime.of(16, 11, 46), + ZoneOffset.ofHours(2)).toInstant()); + Assert.assertEquals(expectedDate, timeStampCreationTime); } @Test From 63db33866000abec9d29032ac868a1c238985259 Mon Sep 17 00:00:00 2001 From: Risto Seene <39149669+rsarendus@users.noreply.github.com> Date: Thu, 13 Apr 2023 14:55:55 +0300 Subject: [PATCH 02/21] DD4J-868 Deprecate validation full report option --- digidoc4j/src/main/java/org/digidoc4j/Configuration.java | 6 ++++++ .../src/main/java/org/digidoc4j/ConfigurationParameter.java | 2 +- .../impl/asic/xades/validation/FullSimpleReportBuilder.java | 1 + .../main/java/org/digidoc4j/main/CommandLineExecutor.java | 1 + digidoc4j/src/main/java/org/digidoc4j/main/DigiDoc4J.java | 2 +- 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/digidoc4j/src/main/java/org/digidoc4j/Configuration.java b/digidoc4j/src/main/java/org/digidoc4j/Configuration.java index 5801afbeb..5c617690c 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/Configuration.java +++ b/digidoc4j/src/main/java/org/digidoc4j/Configuration.java @@ -1901,7 +1901,10 @@ public List getSupportedSslCipherSuitesFor(ExternalConnectionType connec * Set flag if full report needed. * * @param isFullReport needed value. + * + * @deprecated Deprecated for removal. Enabling this feature can, in some cases, produce false negative validation results. */ + @Deprecated public void setFullReportNeeded(boolean isFullReport) { this.setConfigurationParameter(ConfigurationParameter.IsFullSimpleReportNeeded, String.valueOf(isFullReport)); } @@ -1910,7 +1913,10 @@ public void setFullReportNeeded(boolean isFullReport) { * Get flag if full report needed. * * @return isFullReport needed boolean value. + * + * @deprecated Deprecated for removal. Enabling this feature can, in some cases, produce false negative validation results. */ + @Deprecated public boolean isFullReportNeeded() { String isFullSimpleReportNeeded = getConfigurationParameter(ConfigurationParameter.IsFullSimpleReportNeeded); return Boolean.parseBoolean(isFullSimpleReportNeeded != null ? isFullSimpleReportNeeded : Constant.Default.FULL_SIMPLE_REPORT); diff --git a/digidoc4j/src/main/java/org/digidoc4j/ConfigurationParameter.java b/digidoc4j/src/main/java/org/digidoc4j/ConfigurationParameter.java index 5ac860592..a28913385 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/ConfigurationParameter.java +++ b/digidoc4j/src/main/java/org/digidoc4j/ConfigurationParameter.java @@ -54,7 +54,7 @@ public enum ConfigurationParameter { useNonce, AllowASN1UnsafeInteger, PrintValidationReport, - IsFullSimpleReportNeeded, + @Deprecated IsFullSimpleReportNeeded, TslHttpProxyHost("TSL_HTTP_PROXY_HOST"), TslHttpProxyPort("TSL_HTTP_PROXY_PORT"), diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/validation/FullSimpleReportBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/validation/FullSimpleReportBuilder.java index 091a40a24..adca2f5fe 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/validation/FullSimpleReportBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/validation/FullSimpleReportBuilder.java @@ -15,6 +15,7 @@ /** * Created by Andrei on 1.03.2018. */ +@Deprecated public class FullSimpleReportBuilder { private static final Logger log = LoggerFactory.getLogger(FullSimpleReportBuilder.class); diff --git a/digidoc4j/src/main/java/org/digidoc4j/main/CommandLineExecutor.java b/digidoc4j/src/main/java/org/digidoc4j/main/CommandLineExecutor.java index 7878863ec..f9363e170 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/main/CommandLineExecutor.java +++ b/digidoc4j/src/main/java/org/digidoc4j/main/CommandLineExecutor.java @@ -519,6 +519,7 @@ private void verifyContainer(Container container) { if (this.context.getCommandLine().hasOption("verify")) { ContainerVerifier verifier = new ContainerVerifier(this.context.getCommandLine()); if (this.context.getCommandLine().hasOption("showerrors")){ + LOGGER.warn("Option 'err/showerrors' is deprecated; in some cases, it can produce false negative validation results"); Configuration configuration = container.getConfiguration(); configuration.setFullReportNeeded(true); verifier.verify(container, reports); diff --git a/digidoc4j/src/main/java/org/digidoc4j/main/DigiDoc4J.java b/digidoc4j/src/main/java/org/digidoc4j/main/DigiDoc4J.java index 77e4dd0aa..fb4634713 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/main/DigiDoc4J.java +++ b/digidoc4j/src/main/java/org/digidoc4j/main/DigiDoc4J.java @@ -218,7 +218,7 @@ private static Options createParameters() { options.addOption("w", "warnings", false, "show warnings"); options.addOption("version", "version", false, "show version"); options.addOption("tst", "timestamp", false, "adds timestamp token to container"); - options.addOption("err", "showerrors", false, "show container errors"); + options.addOption("err", "showerrors", false, "show container errors [deprecated]"); options.addOption("aiaocsp", "aiaocsp", false, "prefer AIA OCSP in case of LT,LTA signature profiles"); options.addOption(DigiDoc4J.type()); options.addOption(DigiDoc4J.inputFile()); From aee04346d90ff168b5a326b16e68985c8fd6a612 Mon Sep 17 00:00:00 2001 From: nibbydev Date: Thu, 27 Apr 2023 08:37:47 +0300 Subject: [PATCH 03/21] DD4J-877 Remove github actions --- .github/workflows/digidoc4j-verify.yml | 32 -------------------------- README.md | 4 ---- 2 files changed, 36 deletions(-) delete mode 100644 .github/workflows/digidoc4j-verify.yml diff --git a/.github/workflows/digidoc4j-verify.yml b/.github/workflows/digidoc4j-verify.yml deleted file mode 100644 index 5ddeed04e..000000000 --- a/.github/workflows/digidoc4j-verify.yml +++ /dev/null @@ -1,32 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Digidoc4j CI with Maven - -on: - push: - branches: - - master - - develop - pull_request: - branches: - - master - - develop - -jobs: - digidoc4j_build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ ubuntu-20.04 ] - java: [ 8, 11, 17 ] - steps: - - uses: actions/checkout@v2 - - name: Set up JDK - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Build with Maven - env: - TZ: Europe/Helsinki - run: mvn clean verify -q -"Dgpg.skip" diff --git a/README.md b/README.md index 058e20556..5701ebe08 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ ![EU Regional Development Fund](digidoc4j/src/main/doc/resources/EL_Regionaalarengu_Fond_horisontaalne-vaike.jpg) -# Build status - -[![Digidoc4j CI with Maven](https://github.com/open-eid/digidoc4j/actions/workflows/digidoc4j-verify.yml/badge.svg?branch=master)](https://github.com/open-eid/digidoc4j/actions/workflows/digidoc4j-verify.yml) - # DigiDoc4j DigiDoc4j is a Java library for digitally signing documents and creating digital signature containers of signed documents. From 4d49cb022baf365cc2b2c72a9c9cca33531b68bc Mon Sep 17 00:00:00 2001 From: Risto Seene <39149669+rsarendus@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:05:33 +0300 Subject: [PATCH 04/21] DD4J-888 Apply double OCTET STRING wrapping to nonce extension value in CommonOCSPSource --- .../org/digidoc4j/impl/CommonOCSPSource.java | 8 +- .../digidoc4j/impl/SKOnlineOCSPSource.java | 4 + .../digidoc4j/impl/CommonOCSPSourceTest.java | 280 ++++++++++++++---- 3 files changed, 240 insertions(+), 52 deletions(-) diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/CommonOCSPSource.java b/digidoc4j/src/main/java/org/digidoc4j/impl/CommonOCSPSource.java index ff9d0902a..b4f68165f 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/CommonOCSPSource.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/CommonOCSPSource.java @@ -30,6 +30,7 @@ import org.digidoc4j.ServiceType; import org.digidoc4j.TSLCertificateSource; import org.digidoc4j.exceptions.CertificateValidationException; +import org.digidoc4j.exceptions.DigiDoc4JException; import org.digidoc4j.utils.Helper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,7 +96,12 @@ public Extension createNonce(X509Certificate certificate) { return null; } LOGGER.debug("Creating default OCSP nonce ..."); - return new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(Helper.generateRandomBytes(32))); + try { + byte[] nonceValue = new DEROctetString(Helper.generateRandomBytes(32)).getEncoded(); + return new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, nonceValue); + } catch (IOException e) { + throw new DigiDoc4JException(e); + } } @Override diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/SKOnlineOCSPSource.java b/digidoc4j/src/main/java/org/digidoc4j/impl/SKOnlineOCSPSource.java index 615240d54..fecb44799 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/SKOnlineOCSPSource.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/SKOnlineOCSPSource.java @@ -282,6 +282,10 @@ protected DSSPrivateKeyEntry getOCSPAccessCertificatePrivateKey() throws IOExcep protected void checkNonce(BasicOCSPResp response, Extension expectedNonceExtension) { Extension extension = response.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); + if (extension == null) { + String errorMessage = "The OCSP response was expected to contain nonce extension, but no nonce found"; + throw CertificateValidationException.of(CertificateValidationStatus.UNTRUSTED, errorMessage); + } DEROctetString expectedNonce = (DEROctetString) expectedNonceExtension.getExtnValue(); DEROctetString receivedNonce = (DEROctetString) extension.getExtnValue(); if (!receivedNonce.equals(expectedNonce)) { diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java index 93c3ed757..2f592b46b 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java @@ -3,9 +3,15 @@ import eu.europa.esig.dss.model.x509.CertificateToken; import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPToken; import org.apache.commons.lang3.tuple.Pair; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AccessDescription; import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.cert.CertIOException; @@ -28,10 +34,11 @@ import org.digidoc4j.test.util.TestCertificateUtil; import org.digidoc4j.test.util.TestKeyPairUtil; import org.digidoc4j.test.util.TestOcspUtil; -import org.junit.Assert; +import org.hamcrest.Matchers; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; @@ -44,8 +51,16 @@ import java.time.Instant; import java.util.Optional; import java.util.UUID; +import java.util.function.BiConsumer; import java.util.function.Function; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + @RunWith(MockitoJUnitRunner.class) public class CommonOCSPSourceTest extends AbstractTest { @@ -77,13 +92,14 @@ public void getRevocationToken_ocspRespondsWithTrustedOcspCertificate_1elementOc X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[0]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -91,16 +107,17 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificate_1element CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(1); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); CertificateValidationException caughtException = assertThrows( CertificateValidationException.class, () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) ); - Assert.assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -110,13 +127,14 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificate_2element X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[1]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue()[0])); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -124,16 +142,17 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificate_2element CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(2); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue()[0])); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); CertificateValidationException caughtException = assertThrows( CertificateValidationException.class, () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) ); - Assert.assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -143,13 +162,14 @@ public void getRevocationToken_ocspRespondsWithTrustedOcspCertificateAndUntruste X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[0]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -159,13 +179,14 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndTruste X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[1]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -173,16 +194,17 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndUntrus CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(2); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); CertificateValidationException caughtException = assertThrows( CertificateValidationException.class, () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) ); - Assert.assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -192,14 +214,15 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndTruste X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[1]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue()[0], ocspKeyAndCertificates.getValue()[1])); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -209,14 +232,15 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndUntrus X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[2]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue()[0], ocspKeyAndCertificates.getValue()[1])); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -224,17 +248,18 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndUntrus CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(3); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue()[0], ocspKeyAndCertificates.getValue()[1])); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); CertificateValidationException caughtException = assertThrows( CertificateValidationException.class, () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) ); - Assert.assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -244,13 +269,14 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndTruste X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[1]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -260,13 +286,14 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndUntrus X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[2]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -274,16 +301,17 @@ public void getRevocationToken_ocspRespondsWithUntrustedOcspCertificateAndUntrus CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(3); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); CertificateValidationException caughtException = assertThrows( CertificateValidationException.class, () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) ); - Assert.assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -293,13 +321,14 @@ public void getRevocationToken_ocspRespondsWith4elementCertificate_ocspRootInTsl X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[3]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } @Test @@ -309,21 +338,117 @@ public void getRevocationToken_ocspRespondsWith7elementCertificate_ocspFirstInte X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[5]); tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); - preferAiaOcsp(true); + usePreferences(true, true); mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse(ocspRequest, ocspKeyAndCertificates, ocspKeyAndCertificates.getValue())); - SKOnlineOCSPSource ocspSource = createOcspSource(true); + SKOnlineOCSPSource ocspSource = createOcspSource(); OCSPToken ocspToken = ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]); - Assert.assertNotNull(ocspToken); + assertNotNull(ocspToken); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } - private void preferAiaOcsp(boolean preferAiaOcsp) { - Mockito.doReturn(preferAiaOcsp).when(configuration).isAiaOcspPreferred(); + @Test + public void getRevocationToken_WhenOcspRespondsWithoutNonceButNonceExpected_ThrowsCertificateValidationException() { + CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); + Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(1); + X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[0]); + tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); + + usePreferences(true, true); + mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse( + ocspRequest, + (request, responseBuilder) -> responseBuilder.setResponseExtensions(null), + ocspKeyAndCertificates, + ocspKeyAndCertificates.getValue() + )); + SKOnlineOCSPSource ocspSource = createOcspSource(); + + CertificateValidationException caughtException = assertThrows( + CertificateValidationException.class, + () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) + ); + + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertEquals("The OCSP response was expected to contain nonce extension, but no nonce found", caughtException.getMessage()); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); + } + + @Test + public void getRevocationToken_WhenOcspRespondsWithNonMatchingNonce_ThrowsCertificateValidationException() { + CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); + Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(1); + X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[0]); + tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); + + usePreferences(true, true); + mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse( + ocspRequest, + (request, responseBuilder) -> { + byte[] nonceOctets = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue().getOctets(); + nonceOctets[nonceOctets.length - 1] += 1; + Extension newNonceExtension = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, nonceOctets); + responseBuilder.setResponseExtensions(new Extensions(newNonceExtension)); + }, + ocspKeyAndCertificates, + ocspKeyAndCertificates.getValue() + )); + SKOnlineOCSPSource ocspSource = createOcspSource(); + + CertificateValidationException caughtException = assertThrows( + CertificateValidationException.class, + () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) + ); + + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertThat(caughtException.getMessage(), matchesPattern( + "The OCSP request was victim of the replay attack \\(nonce sent <#([0-9a-f]{66})[0-9a-f]{2}>, nonce received <#\\1[0-9a-f]{2}>\\)" + )); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); + } + + @Test + public void getRevocationToken_WhenOcspRespondsWithIncorrectlyWrappedNonce_ThrowsCertificateValidationException() { + CertificateToken[] signerCertificateChain = issueSignerCertificateChain(2); + Pair ocspKeyAndCertificates = issueOcspKeyAndCertificateChain(1); + X509Certificate ocspTrustedCertificate = TestCertificateUtil.toX509Certificate(ocspKeyAndCertificates.getValue()[0]); + tslCertificateSource.addTSLCertificate(ocspTrustedCertificate); + + usePreferences(true, true); + mockDataLoaderPostResponse(MOCK_OCSP_URL, ocspRequest -> createOcspResponse( + ocspRequest, + (request, responseBuilder) -> { + ASN1OctetString extnValue = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue(); + ASN1OctetString nonceOctetString = ASN1OctetString.getInstance(extnValue.getOctets()); + Extension newNonceExtension = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, nonceOctetString.getOctets()); + responseBuilder.setResponseExtensions(new Extensions(newNonceExtension)); + }, + ocspKeyAndCertificates, + ocspKeyAndCertificates.getValue() + )); + SKOnlineOCSPSource ocspSource = createOcspSource(); + + CertificateValidationException caughtException = assertThrows( + CertificateValidationException.class, + () -> ocspSource.getRevocationToken(signerCertificateChain[0], signerCertificateChain[1]) + ); + + assertEquals(CertificateValidationException.CertificateValidationStatus.UNTRUSTED, caughtException.getCertificateStatus()); + assertThat(caughtException.getMessage(), matchesPattern( + "The OCSP request was victim of the replay attack \\(nonce sent <#0420([0-9a-f]+)>, nonce received <#\\1>\\)" + )); + verifyDataLoaderPostInteraction(MOCK_OCSP_URL, true, true); } - private CommonOCSPSource createOcspSource(boolean useNonce) { + private void usePreferences(boolean preferAiaOcsp, boolean useNonce) { + Mockito.doReturn(preferAiaOcsp).when(configuration).isAiaOcspPreferred(); Mockito.doReturn(useNonce).when(configuration).isOcspNonceUsed(); + if (preferAiaOcsp) { + Mockito.doReturn(useNonce).when(configuration).getUseNonceForAiaOcspByCN(Mockito.anyString()); + } + } + + private CommonOCSPSource createOcspSource() { CommonOCSPSource commonOCSPSource = new CommonOCSPSource(configuration); commonOCSPSource.setDataLoader(ocspDataLoader); return commonOCSPSource; @@ -336,7 +461,38 @@ private void mockDataLoaderPostResponse(String requestUrl, Function issueCertificate(Pair issuer, String subjectDn, ExtensionAdder extensionAdder) { + private void verifyDataLoaderPostInteraction(String requestUrl, boolean preferAiaOcsp, boolean useNonce) { + ArgumentCaptor postContentCaptor = ArgumentCaptor.forClass(byte[].class); + Mockito.verify(ocspDataLoader).post(Mockito.eq(requestUrl), postContentCaptor.capture()); + Mockito.verify(ocspDataLoader).setAsAiaOcsp(preferAiaOcsp); + Mockito.verifyNoMoreInteractions(ocspDataLoader); + + byte[] postContent = postContentCaptor.getValue(); + OCSPReq ocspReq = parseOcspRequest(postContent); + + Extension ocspNonceExtension = ocspReq.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); + if (useNonce) { + assertNotNull(ocspNonceExtension); + try { + ASN1OctetString nonceValue = ocspNonceExtension.getExtnValue(); + assertThat(nonceValue, Matchers.instanceOf(DEROctetString.class)); + ASN1Primitive nonceValueContent = ASN1Primitive.fromByteArray(nonceValue.getOctets()); + assertThat(nonceValueContent, Matchers.instanceOf(DEROctetString.class)); + byte[] nonceValueContentOctets = ((DEROctetString) nonceValueContent).getOctets(); + assertEquals(32, nonceValueContentOctets.length); + } catch (IOException e) { + fail("Failed to verify nonce: " + e.getMessage()); + } + } else { + assertNull(ocspNonceExtension); + } + } + + private static Pair issueCertificate( + Pair issuer, + String subjectDn, + ExtensionAdder extensionAdder + ) { AsymmetricCipherKeyPair keyPair = TestKeyPairUtil.generateEcKeyPair("secp384r1"); PrivateKey privateKey = TestKeyPairUtil.toPrivateKey((ECPrivateKeyParameters) keyPair.getPrivate()); PublicKey publicKey = TestKeyPairUtil.toPublicKey((ECPublicKeyParameters) keyPair.getPublic()); @@ -428,9 +584,31 @@ private static Pair issueOcspKeyAndCertific return Pair.of(issuerKeyAndCertificate.getKey(), certificateChain); } - private static byte[] createOcspResponse(byte[] ocspRequestBytes, Pair ocspSignerKeyAndCertificateChain, X509CertificateHolder... certificatesToPutIntoResponse) { + private static byte[] createOcspResponse( + byte[] ocspRequestBytes, + Pair ocspSignerKeyAndCertificateChain, + X509CertificateHolder... certificatesToPutIntoResponse + ) { + return createOcspResponse( + ocspRequestBytes, + (request, responseBuilder) -> Optional + .ofNullable(request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce)) + .map(Extensions::new) + .ifPresent(responseBuilder::setResponseExtensions), + ocspSignerKeyAndCertificateChain, + certificatesToPutIntoResponse + ); + } + + private static byte[] createOcspResponse( + byte[] ocspRequestBytes, + BiConsumer responseBuilderConfigurator, + Pair ocspSignerKeyAndCertificateChain, + X509CertificateHolder... certificatesToPutIntoResponse + ) { OCSPReq request = parseOcspRequest(ocspRequestBytes); BasicOCSPRespBuilder basicOCSPRespBuilder = TestOcspUtil.createBasicOCSPRespBuilder(ocspSignerKeyAndCertificateChain.getValue()[0]); + responseBuilderConfigurator.accept(request, basicOCSPRespBuilder); for (Req req : request.getRequestList()) { basicOCSPRespBuilder.addResponse(req.getCertID(), org.bouncycastle.cert.ocsp.CertificateStatus.GOOD); } From 110cbcc05b7986927091fdb5121dd75333747d11 Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Wed, 21 Jun 2023 10:51:16 +0300 Subject: [PATCH 05/21] DD4J-869 Use LinkedHashMap in ManifestParser to retain the original order of the parsed elements --- .../impl/asic/manifest/ManifestEntry.java | 35 ++++---- .../impl/asic/manifest/ManifestParser.java | 20 ++--- .../asic/manifest/ManifestParserTest.java | 89 ++++++++++++++++--- 3 files changed, 105 insertions(+), 39 deletions(-) diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestEntry.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestEntry.java index e3c8af0fc..8ab30edb4 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestEntry.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestEntry.java @@ -1,18 +1,19 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.asic.manifest; import java.io.Serializable; import java.util.Objects; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,15 +21,17 @@ * Contains information of filenames and mimetypes. */ public final class ManifestEntry implements Serializable{ + private static final Logger logger = LoggerFactory.getLogger(ManifestEntry.class); - private String fileName; - private String mimeType; + + private final String fileName; + private final String mimeType; /** * ManifestEntry constructor * - * @param fileName - * @param mimeType + * @param fileName filename + * @param mimeType mimetype */ public ManifestEntry(String fileName, String mimeType) { this.fileName = fileName; @@ -58,10 +61,9 @@ public String getMimeType() { @Override public boolean equals(Object obj) { if (obj instanceof ManifestEntry) { - if (fileName.equals(((ManifestEntry)obj).getFileName()) - && mimeType.equals(((ManifestEntry)obj).getMimeType())) { - return true; - } + ManifestEntry manifestEntry = (ManifestEntry) obj; + return StringUtils.equals(fileName, manifestEntry.getFileName()) + && StringUtils.equals(mimeType, manifestEntry.getMimeType()); } return false; } @@ -70,4 +72,5 @@ public boolean equals(Object obj) { public int hashCode() { return Objects.hash(fileName, mimeType); } + } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestParser.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestParser.java index c7e066d5e..04605e3ac 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestParser.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestParser.java @@ -1,12 +1,12 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.asic.manifest; @@ -23,7 +23,7 @@ import java.io.Serializable; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; public class ManifestParser implements Serializable { @@ -45,7 +45,7 @@ public Map getManifestFileItems() { if (!containsManifestFile()) { return Collections.emptyMap(); } - entries = new HashMap<>(); + entries = new LinkedHashMap<>(); loadFileEntriesFromManifest(); return entries; } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/asic/manifest/ManifestParserTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/manifest/ManifestParserTest.java index e966de964..42491724a 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/asic/manifest/ManifestParserTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/manifest/ManifestParserTest.java @@ -1,33 +1,96 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.impl.asic.manifest; import eu.europa.esig.dss.model.FileDocument; -import org.junit.Assert; +import eu.europa.esig.dss.model.InMemoryDocument; +import org.digidoc4j.DataFile; import org.junit.Test; +import java.util.Arrays; import java.util.Map; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.hamcrest.Matchers.hasEntry; + public class ManifestParserTest { @Test - public void parseValidManifest() { + public void getManifestFileItems_WhenManifestIsValid_ReturnsMapOfAllItems() { FileDocument manifestFile = new FileDocument("src/test/resources/testFiles/manifest/valid-manifest.xml"); ManifestParser parser = new ManifestParser(manifestFile); - Map items = parser.getManifestFileItems(); - Assert.assertEquals(2, items.size()); - Assert.assertTrue(items.containsKey("sample_file.pdf")); - ManifestEntry entry = items.get("sample_file.pdf"); - Assert.assertEquals("application/pdf", entry.getMimeType()); + + Map result = parser.getManifestFileItems(); + + assertThat(result, aMapWithSize(2)); + assertThat(result, hasEntry("DigiDocService_spec_est.pdf", + new ManifestEntry("DigiDocService_spec_est.pdf", "text/plain"))); + assertThat(result, hasEntry("sample_file.pdf", + new ManifestEntry("sample_file.pdf", "application/pdf"))); } @Test - public void parseManifestWithInvalidNamespace() { + public void getManifestFileItems_WhenManifestNamespaceIsInvalid_ReturnsMapOfAllItems() { FileDocument manifestFile = new FileDocument("src/test/resources/testFiles/manifest/manifest-with-different-namespace.xml"); ManifestParser parser = new ManifestParser(manifestFile); - Map items = parser.getManifestFileItems(); - Assert.assertEquals(1, items.size()); - Assert.assertTrue(items.containsKey("datafile.txt")); - ManifestEntry entry = items.get("datafile.txt"); - Assert.assertEquals("text/plain", entry.getMimeType()); + + Map result = parser.getManifestFileItems(); + + assertThat(result, aMapWithSize(1)); + assertThat(result, hasEntry("datafile.txt", + new ManifestEntry("datafile.txt", "text/plain"))); + } + + @Test + public void getManifestFileItems_WhenMultipleEntriesAreInLexicalOrder_ReturnsMapOfAllItemsRetainingTheirOrder() { + AsicManifest asicManifest = new AsicManifest(); + asicManifest.addFileEntries(Arrays.asList( + new DataFile(new byte[0], "a.txt", "text/plain"), + new DataFile(new byte[0], "b.txt", "text/plain"), + new DataFile(new byte[0], "c.txt", "text/plain"), + new DataFile(new byte[0], "d.txt", "text/plain"), + new DataFile(new byte[0], "e.txt", "text/plain") + )); + InMemoryDocument manifestFile = new InMemoryDocument(asicManifest.getBytes()); + ManifestParser parser = new ManifestParser(manifestFile); + + Map result = parser.getManifestFileItems(); + + assertThat(result, aMapWithSize(5)); + assertThat(result.keySet(), containsInRelativeOrder( + "a.txt", "b.txt", "c.txt", "d.txt", "e.txt" + )); + } + + @Test + public void getManifestFileItems_WhenMultipleEntriesAreInNonLexicalOrder_ReturnsMapOfAllItemsRetainingTheirOrder() { + AsicManifest asicManifest = new AsicManifest(); + asicManifest.addFileEntries(Arrays.asList( + new DataFile(new byte[0], "c.txt", "text/plain"), + new DataFile(new byte[0], "a.txt", "text/plain"), + new DataFile(new byte[0], "e.txt", "text/plain"), + new DataFile(new byte[0], "d.txt", "text/plain"), + new DataFile(new byte[0], "b.txt", "text/plain") + )); + InMemoryDocument manifestFile = new InMemoryDocument(asicManifest.getBytes()); + ManifestParser parser = new ManifestParser(manifestFile); + + Map result = parser.getManifestFileItems(); + + assertThat(result, aMapWithSize(5)); + assertThat(result.keySet(), containsInRelativeOrder( + "c.txt", "a.txt", "e.txt", "d.txt", "b.txt" + )); } } From 7bb71d49b5ce52ebfda14ff130598051b5cbb476 Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Wed, 21 Jun 2023 10:53:06 +0300 Subject: [PATCH 06/21] DD4J-869 Update the certificate count assertion of a failing test-TSL test --- digidoc4j/src/test/java/org/digidoc4j/ConfigurationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digidoc4j/src/test/java/org/digidoc4j/ConfigurationTest.java b/digidoc4j/src/test/java/org/digidoc4j/ConfigurationTest.java index 980695193..b8b0fe66d 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/ConfigurationTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/ConfigurationTest.java @@ -279,7 +279,7 @@ public void TSLIsLoadedAfterSettingNewLOTLLocation() throws Exception { BDocContainer container = (BDocContainer) ContainerBuilder.aContainer(Container.DocumentType.BDOC) .withConfiguration(this.configuration).build(); container.getConfiguration().getTSL(); - Assert.assertEquals(15, container.getConfiguration().getTSL().getCertificates().size()); + Assert.assertEquals(25, container.getConfiguration().getTSL().getCertificates().size()); int tenSeconds = 10000; String lotlHost = "10.0.25.57"; From 923c4e50788fbd6dcefacab78a16aa00c975cb1c Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Tue, 11 Jul 2023 13:33:34 +0300 Subject: [PATCH 07/21] DD4J-890 Disable the creation of LT_TM and B_EPES signatures --- .../DetachedXadesSignatureBuilder.java | 28 +- .../java/org/digidoc4j/SignatureBuilder.java | 55 +- .../digidoc4j/SignatureFinalizerBuilder.java | 21 +- .../digidoc4j/impl/SignatureFinalizer.java | 2 +- .../impl/asic/AsicSignatureBuilder.java | 12 +- .../impl/asic/AsicSignatureFinalizer.java | 31 +- .../asic/asice/AsicESignatureBuilder.java | 17 +- .../asic/asice/AsicESignatureFinalizer.java | 13 +- .../impl/asic/asice/AsicESignatureOpener.java | 53 +- .../asic/asice/bdoc/BDocSignatureBuilder.java | 10 - .../asice/bdoc/BDocSignatureFinalizer.java | 60 - .../asic/asice/bdoc/BDocSignatureOpener.java | 53 +- .../impl/asic/asics/AsicSContainer.java | 3 +- .../asic/asics/AsicSSignatureBuilder.java | 39 + .../asic/asics/AsicSSignatureFinalizer.java | 48 + .../impl/asic/asics/AsicSSignatureOpener.java | 38 + .../impl/asic/manifest/ManifestValidator.java | 10 +- .../asic/xades/AsicXadesSignatureOpener.java | 64 + .../impl/asic/xades/SignatureExtender.java | 61 +- .../java/org/digidoc4j/utils/PolicyUtils.java | 1 + .../test/java/org/digidoc4j/AbstractTest.java | 26 +- .../test/java/org/digidoc4j/AiaOcspTest.java | 27 +- .../DetachedXadesSignatureBuilderTest.java | 370 ++--- .../org/digidoc4j/SignatureBuilderTest.java | 1221 ++++++++++++----- .../SignatureFinalizerBuilderTest.java | 108 +- .../java/org/digidoc4j/SignatureTest.java | 82 +- ...ingWithOutDataToSignSerializationTest.java | 46 +- .../impl/DataToSignSerializationTest.java | 75 +- .../EmptyDataFilesSignatureFinalizerTest.java | 13 +- .../asic/asice/AsicESignatureOpenerTest.java | 32 + .../asice/bdoc/BDocSignatureOpenerTest.java | 32 + .../asic/asics/AsicSSignatureOpenerTest.java | 32 + ...DataFilesAsicSSignatureFinalizerTest.java} | 7 +- .../xades/AsicXadesSignatureOpenerTest.java} | 32 +- .../impl/bdoc/BDocContainerTest.java | 601 ++++---- .../impl/bdoc/BDocSerializationTest.java | 43 +- .../bdoc/ContainerParticlesRemovalTest.java | 81 +- ...tyDataFilesBdocSignatureFinalizerTest.java | 18 - .../impl/bdoc/ExtendingBDocContainerTest.java | 322 +++-- .../impl/bdoc/IncompleteSigningTest.java | 250 ++-- .../impl/bdoc/SignatureTimeTest.java | 46 +- .../impl/bdoc/asic/AsicSerializationTest.java | 20 +- .../bdoc/asic/AsicSignatureFinalizerTest.java | 20 +- ...yDataFilesAsicESignatureFinalizerTest.java | 10 + .../bdoc/report/ValidationReportTest.java | 32 +- 45 files changed, 2526 insertions(+), 1639 deletions(-) delete mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureBuilder.java delete mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureFinalizer.java create mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureBuilder.java create mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureFinalizer.java create mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpener.java create mode 100644 digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpener.java create mode 100644 digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpenerTest.java create mode 100644 digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpenerTest.java create mode 100644 digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpenerTest.java rename digidoc4j/src/test/java/org/digidoc4j/impl/{bdoc/asic/EmptyDataFilesAsicSignatureFinalizerTest.java => asic/asics/EmptyDataFilesAsicSSignatureFinalizerTest.java} (53%) rename digidoc4j/src/test/java/org/digidoc4j/impl/{bdoc/BDocSignatureOpenerTest.java => asic/xades/AsicXadesSignatureOpenerTest.java} (86%) delete mode 100644 digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/EmptyDataFilesBdocSignatureFinalizerTest.java diff --git a/digidoc4j/src/main/java/org/digidoc4j/DetachedXadesSignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/DetachedXadesSignatureBuilder.java index a9bb0981f..f180a25b0 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/DetachedXadesSignatureBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/DetachedXadesSignatureBuilder.java @@ -23,7 +23,6 @@ import org.digidoc4j.utils.CertificateUtils; import org.digidoc4j.utils.DigestUtils; import org.digidoc4j.utils.Helper; -import org.digidoc4j.utils.PolicyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -183,36 +182,29 @@ public DetachedXadesSignatureBuilder withEncryptionAlgorithm(EncryptionAlgorithm } /** - * Set a signature profile: Time Mark, Time Stamp, Archive Time Stamp or no profile. Default is Time Stamp. + * Set a signature profile: Time Stamp, Archive Time Stamp or no profile. Default is Time Stamp. * * @param signatureProfile signature profile. * @return builder for creating a signature. */ public DetachedXadesSignatureBuilder withSignatureProfile(SignatureProfile signatureProfile) { - Policy policyDefinedByUser = signatureParameters.getPolicy(); - if (policyDefinedByUser != null && PolicyUtils.areAllPolicyValuesDefined(policyDefinedByUser) - && signatureProfile != SignatureProfile.LT_TM) { - logger.debug("policyDefinedByUser:" + policyDefinedByUser.toString()); - logger.debug("signatureProfile:" + signatureProfile.toString()); - throw new NotSupportedException("Can't define signature policy if it's not LT_TM signature profile "); + if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureProfile)) { + throw new NotSupportedException(String.format("Can't create %s signatures", signatureProfile)); } signatureParameters.setSignatureProfile(signatureProfile); return this; } /** - * Set signature policy parameters. Define signature profile first. + * Set signature policy parameters. +

+ The default implementation throws {@code NotSupportedException}. * * @param signaturePolicy with defined parameters. * @return SignatureBuilder */ public DetachedXadesSignatureBuilder withOwnSignaturePolicy(Policy signaturePolicy) { - if (signatureParameters.getSignatureProfile() != null - && signatureParameters.getSignatureProfile() != SignatureProfile.LT_TM) { - throw new NotSupportedException("Can't define signature policy if it's not LT_TM signature profile. Define it first. "); - } - signatureParameters.setPolicy(signaturePolicy); - return this; + throw new NotSupportedException("Can't define signature policy"); } /** @@ -309,11 +301,7 @@ protected void setConfiguration(Configuration configuration) { private SignatureFinalizer getSignatureFinalizer() { if (signatureFinalizer == null) { populateSignatureParameters(); - if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile())) { - signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(dataFiles, signatureParameters, configuration, Container.DocumentType.BDOC); - } else { - signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(dataFiles, signatureParameters, configuration, Container.DocumentType.ASICE); - } + signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(dataFiles, signatureParameters, configuration, Container.DocumentType.ASICE); } return signatureFinalizer; } diff --git a/digidoc4j/src/main/java/org/digidoc4j/SignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/SignatureBuilder.java index 3523a3c25..07ad94bc0 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/SignatureBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/SignatureBuilder.java @@ -1,12 +1,12 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j; @@ -17,10 +17,8 @@ import org.digidoc4j.exceptions.SignatureTokenMissingException; import org.digidoc4j.exceptions.SignerCertificateRequiredException; import org.digidoc4j.exceptions.TechnicalException; -import org.digidoc4j.impl.asic.AsicSignatureBuilder; import org.digidoc4j.impl.asic.asice.AsicESignatureBuilder; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureBuilder; -import org.digidoc4j.utils.PolicyUtils; +import org.digidoc4j.impl.asic.asics.AsicSSignatureBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +44,7 @@ *    {@link SignatureBuilder#withCountry(String) withCountry("Val Verde")}.
*    {@link SignatureBuilder#withRoles(String...) withRoles("Manager", "Suspicious Fisherman")}.
*    {@link SignatureBuilder#withSignatureDigestAlgorithm(DigestAlgorithm) withSignatureDigestAlgorithm(DigestAlgorithm.SHA256)}. // Digest algorithm is SHA-256
- *    {@link SignatureBuilder#withSignatureProfile(SignatureProfile) withSignatureProfile(SignatureProfile.LT_TM)}. // Signature profile is Time-Mark
+ *    {@link SignatureBuilder#withSignatureProfile(SignatureProfile) withSignatureProfile(SignatureProfile.LT)}. // Signature profile is Time Stamp
*    {@link SignatureBuilder#withSigningCertificate(X509Certificate) withSigningCertificate(x509Certificate)}.
*    {@link SignatureBuilder#withSignatureId(String) withSignatureId("1")}.
*    {@link SignatureBuilder#withSignatureToken(SignatureToken) withSignatureToken(signatureToken)}. // Use signature token
@@ -89,12 +87,10 @@ public static SignatureBuilder aSignature(Container container) { private static SignatureBuilder createBuilder(String containerType) { if (isCustomContainerType(containerType)) { return createCustomSignatureBuilder(containerType); - } else if (isContainerType(containerType, BDOC_CONTAINER_TYPE)) { - return new BDocSignatureBuilder(); - } else if (isContainerType(containerType, ASICE_CONTAINER_TYPE)) { + } else if (StringUtils.equalsAnyIgnoreCase(containerType, ASICE_CONTAINER_TYPE, BDOC_CONTAINER_TYPE)) { return new AsicESignatureBuilder(); - } else if (isContainerType(containerType, ASICS_CONTAINER_TYPE)) { - return new AsicSignatureBuilder(); + } else if (StringUtils.equalsIgnoreCase(containerType, ASICS_CONTAINER_TYPE)) { + return new AsicSSignatureBuilder(); } else { logger.error("Unknown container type: {}", containerType); throw new NotSupportedException("Unknown container type: " + containerType); @@ -125,10 +121,6 @@ private static boolean isCustomContainerType(String containerType) { return customSignatureBuilders.containsKey(containerType); } - private static boolean isContainerType(String containerType, String ddocContainerType) { - return StringUtils.equalsIgnoreCase(ddocContainerType, containerType); - } - private static SignatureBuilder createCustomSignatureBuilder(String containerType) { Class builderClass = customSignatureBuilders.get(containerType); try { @@ -274,18 +266,14 @@ public SignatureBuilder withDataFileDigestAlgorithm(DigestAlgorithm digestAlgori } /** - * Set a signature profile: Time Mark, Time Stamp, Archive Time Stamp or no profile. Default is Time Stamp. + * Set a signature profile: Time Stamp, Archive Time Stamp or no profile. Default is Time Stamp. * * @param signatureProfile signature profile. * @return builder for creating a signature. */ public SignatureBuilder withSignatureProfile(SignatureProfile signatureProfile) { - Policy policyDefinedByUser = signatureParameters.getPolicy(); - if (policyDefinedByUser != null && PolicyUtils.areAllPolicyValuesDefined(policyDefinedByUser) - && signatureProfile != SignatureProfile.LT_TM) { - logger.debug("policyDefinedByUser:" + policyDefinedByUser.toString()); - logger.debug("signatureProfile:" + signatureProfile.toString()); - throw new NotSupportedException("Can't define signature policy if it's not LT_TM signature profile "); + if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureProfile)) { + throw new NotSupportedException(String.format("Can't create %s signatures", signatureProfile)); } signatureParameters.setSignatureProfile(signatureProfile); return this; @@ -340,17 +328,14 @@ protected void setContainer(Container container) { } /** - * Set signature policy parameters. Define signature profile first. + * Set signature policy parameters. + *

+ * The default implementation throws {@code NotSupportedException}. * * @param signaturePolicy with defined parameters. * @return SignatureBuilder */ public SignatureBuilder withOwnSignaturePolicy(Policy signaturePolicy) { - if (signatureParameters.getSignatureProfile() != null - && signatureParameters.getSignatureProfile() != SignatureProfile.LT_TM) { - throw new NotSupportedException("Can't define signature policy if it's not LT_TM signature profile. Define it first. "); - } - signatureParameters.setPolicy(signaturePolicy); - return this; + throw new NotSupportedException("Can't define signature policy"); } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/SignatureFinalizerBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/SignatureFinalizerBuilder.java index 354aad26e..c14bb0af6 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/SignatureFinalizerBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/SignatureFinalizerBuilder.java @@ -13,25 +13,20 @@ import org.apache.commons.lang3.StringUtils; import org.digidoc4j.exceptions.NotSupportedException; import org.digidoc4j.impl.SignatureFinalizer; -import org.digidoc4j.impl.asic.AsicSignatureFinalizer; import org.digidoc4j.impl.asic.asice.AsicESignatureFinalizer; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureFinalizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; import static org.digidoc4j.Container.DocumentType.ASICE; import static org.digidoc4j.Container.DocumentType.ASICS; import static org.digidoc4j.Container.DocumentType.BDOC; +import static org.digidoc4j.Container.DocumentType.DDOC; /** * Builder for creating a signature finalizer for finalizing signing process. */ public final class SignatureFinalizerBuilder { - private static final Logger LOGGER = LoggerFactory.getLogger(SignatureFinalizerBuilder.class); - /** * Create a new signature finalizer based on a container and signature parameters. * Container type is used to determine which type of signature finalizer should be created. @@ -67,19 +62,15 @@ public static SignatureFinalizer aFinalizer(List dataFilesToSign, Sign } private static SignatureFinalizer determineFinalizer(List dataFilesToSign, SignatureParameters signatureParameters, Configuration configuration, String documentType) { - if (isDocumentOfType(documentType, BDOC.name())) { - return new BDocSignatureFinalizer(dataFilesToSign, signatureParameters, configuration); - } else if (isDocumentOfType(documentType, ASICE.name())) { + if (StringUtils.equalsAnyIgnoreCase(documentType, ASICE.name(), BDOC.name())) { return new AsicESignatureFinalizer(dataFilesToSign, signatureParameters, configuration); - } else if (isDocumentOfType(documentType, ASICS.name())) { - return new AsicSignatureFinalizer(dataFilesToSign, signatureParameters, configuration); + } else if (StringUtils.equalsIgnoreCase(documentType, ASICS.name())) { + throw new NotSupportedException("Creation of ASiC-S signatures is not supported"); + } else if (StringUtils.equalsIgnoreCase(documentType, DDOC.name())) { + throw new NotSupportedException("Creation of DDOC signatures is not supported"); } else { - LOGGER.error("Unknown document type: {}", documentType); throw new NotSupportedException("Unknown document type: " + documentType); } } - private static boolean isDocumentOfType(String actualDocumentType, String expectedDocumentType) { - return StringUtils.equalsIgnoreCase(expectedDocumentType, actualDocumentType); - } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/SignatureFinalizer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/SignatureFinalizer.java index f2aed3d9a..a76dad6aa 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/SignatureFinalizer.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/SignatureFinalizer.java @@ -32,7 +32,7 @@ public abstract class SignatureFinalizer implements Serializable { protected SignatureParameters signatureParameters; protected Configuration configuration; - public SignatureFinalizer(List dataFiles, SignatureParameters signatureParameters, Configuration configuration) { + protected SignatureFinalizer(List dataFiles, SignatureParameters signatureParameters, Configuration configuration) { verifyDataFilesNotEmpty(dataFiles); this.dataFiles = dataFiles; this.signatureParameters = signatureParameters; diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureBuilder.java index 7a9e7fece..766d47919 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureBuilder.java @@ -18,7 +18,6 @@ import org.digidoc4j.EncryptionAlgorithm; import org.digidoc4j.Signature; import org.digidoc4j.SignatureBuilder; -import org.digidoc4j.SignatureFinalizerBuilder; import org.digidoc4j.SignatureProfile; import org.digidoc4j.exceptions.ContainerWithoutFilesException; import org.digidoc4j.exceptions.InvalidSignatureException; @@ -36,7 +35,7 @@ /** * Signature builder for Asic container. */ -public class AsicSignatureBuilder extends SignatureBuilder { +public abstract class AsicSignatureBuilder extends SignatureBuilder { private static final Logger logger = LoggerFactory.getLogger(AsicSignatureBuilder.class); private SignatureFinalizer signatureFinalizer; @@ -80,10 +79,12 @@ public Configuration getConfiguration() { return container.getConfiguration(); } + protected abstract SignatureFinalizer createSignatureFinalizer(); + private SignatureFinalizer getSignatureFinalizer() { if (signatureFinalizer == null) { populateSignatureParameters(); - this.signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(container, signatureParameters); + this.signatureFinalizer = createSignatureFinalizer(); } return signatureFinalizer; } @@ -131,7 +132,6 @@ private void populateSignatureProfile() { } } - protected void validateSignatureCompatibilityWithContainer() { - // Do nothing - } + protected abstract void validateSignatureCompatibilityWithContainer(); + } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureFinalizer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureFinalizer.java index 8f521d6b5..801c900fb 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureFinalizer.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/AsicSignatureFinalizer.java @@ -22,20 +22,18 @@ import org.digidoc4j.EncryptionAlgorithm; import org.digidoc4j.OCSPSourceBuilder; import org.digidoc4j.Signature; -import org.digidoc4j.SignatureContainerMatcherValidator; import org.digidoc4j.SignatureParameters; import org.digidoc4j.SignatureProfile; import org.digidoc4j.X509Cert; import org.digidoc4j.exceptions.CertificateValidationException; import org.digidoc4j.exceptions.ContainerWithoutFilesException; import org.digidoc4j.exceptions.DigiDoc4JException; +import org.digidoc4j.exceptions.NotSupportedException; import org.digidoc4j.exceptions.OCSPRequestFailedException; import org.digidoc4j.impl.AiaSourceFactory; import org.digidoc4j.impl.SKOnlineOCSPSource; import org.digidoc4j.impl.SignatureFinalizer; import org.digidoc4j.impl.TspDataLoaderFactory; -import org.digidoc4j.impl.asic.asice.AsicESignatureOpener; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureOpener; import org.digidoc4j.impl.asic.xades.XadesSignature; import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import org.digidoc4j.impl.asic.xades.XadesSigningDssFacade; @@ -57,7 +55,7 @@ /** * Asic signature finalizer for datafiles signing process. */ -public class AsicSignatureFinalizer extends SignatureFinalizer { +public abstract class AsicSignatureFinalizer extends SignatureFinalizer { public static final int HEX_MAX_LENGTH = 10; protected transient XadesSigningDssFacade facade; @@ -66,7 +64,7 @@ public class AsicSignatureFinalizer extends SignatureFinalizer { private boolean isLTorLTAProfile = false; - public AsicSignatureFinalizer(List dataFilesToSign, SignatureParameters signatureParameters, Configuration configuration) { + protected AsicSignatureFinalizer(List dataFilesToSign, SignatureParameters signatureParameters, Configuration configuration) { super(dataFilesToSign, signatureParameters, configuration); } @@ -98,15 +96,8 @@ public Signature createSignature(DSSDocument signedDocument) { } List detachedContents = detachedContentCreator.getDetachedContentList(); XadesSignatureWrapper signatureWrapper = parseSignatureWrapper(signedDocument, detachedContents); + AsicSignature signature = asAsicSignature(signatureWrapper); - AsicSignature signature; - if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile())) { - BDocSignatureOpener signatureOpener = new BDocSignatureOpener(configuration); - signature = signatureOpener.open(signatureWrapper); - } else { - AsicESignatureOpener signatureOpener = new AsicESignatureOpener(configuration); - signature = signatureOpener.open(signatureWrapper); - } validateOcspResponse(signature.getOrigin()); validateTimestampResponse(signature.getOrigin()); LOGGER.info("Signing asic successfully completed"); @@ -125,9 +116,9 @@ public byte[] getDataToBeSigned() { return dataToSign; } - protected void validateSignatureCompatibility() { - // Do nothing - } + protected abstract AsicSignature asAsicSignature(XadesSignatureWrapper signatureWrapper); + + protected abstract void validateSignatureCompatibility(); private void populateParametersForFinalizingSignature(byte[] signatureValueBytes) { initSigningFacade(); @@ -236,16 +227,18 @@ private void setSignatureProfile() { private void setSignatureProfile(SignatureProfile profile) { switch (profile) { case B_BES: - case B_EPES: facade.setSignatureLevel(XAdES_BASELINE_B); break; + case LT: + isLTorLTAProfile = true; + facade.setSignatureLevel(XAdES_BASELINE_LT); + break; case LTA: isLTorLTAProfile = true; facade.setSignatureLevel(XAdES_BASELINE_LTA); break; default: - isLTorLTAProfile = true; - facade.setSignatureLevel(XAdES_BASELINE_LT); + throw new NotSupportedException(String.format("%s profile is not supported for ASiC signatures", profile)); } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureBuilder.java index 46c37072c..b96774704 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureBuilder.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureBuilder.java @@ -1,9 +1,20 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.impl.asic.asice; import org.apache.commons.lang3.StringUtils; import org.digidoc4j.Container; import org.digidoc4j.SignatureContainerMatcherValidator; import org.digidoc4j.exceptions.IllegalSignatureProfileException; +import org.digidoc4j.impl.SignatureFinalizer; import org.digidoc4j.impl.asic.AsicSignatureBuilder; /** @@ -11,9 +22,13 @@ */ public class AsicESignatureBuilder extends AsicSignatureBuilder { + @Override + protected SignatureFinalizer createSignatureFinalizer() { + return new AsicESignatureFinalizer(container.getDataFiles(), signatureParameters, getConfiguration()); + } + @Override protected void validateSignatureCompatibilityWithContainer() { - super.validateSignatureCompatibilityWithContainer(); if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile()) && isAsicEContainer()) { throw new IllegalSignatureProfileException( "Cannot add BDoc specific (" + signatureParameters.getSignatureProfile() + ") signature to ASiCE container"); diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureFinalizer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureFinalizer.java index df689ec56..e3e906765 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureFinalizer.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureFinalizer.java @@ -15,7 +15,9 @@ import org.digidoc4j.SignatureContainerMatcherValidator; import org.digidoc4j.SignatureParameters; import org.digidoc4j.exceptions.IllegalSignatureProfileException; +import org.digidoc4j.impl.asic.AsicSignature; import org.digidoc4j.impl.asic.AsicSignatureFinalizer; +import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import java.util.List; @@ -29,16 +31,17 @@ public AsicESignatureFinalizer(List dataFilesToSign, SignatureParamete } @Override - protected void setSignaturePolicy() { - // Do nothing + protected AsicSignature asAsicSignature(XadesSignatureWrapper signatureWrapper) { + return new AsicESignatureOpener(configuration).open(signatureWrapper); } @Override protected void validateSignatureCompatibility() { - super.validateSignatureCompatibility(); if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile())) { - throw new IllegalSignatureProfileException( - "Cannot add BDoc specific (" + signatureParameters.getSignatureProfile() + ") signature to ASiCE container"); + throw new IllegalSignatureProfileException(String.format( + "Cannot create BDoc specific (%s) signature", + signatureParameters.getSignatureProfile() + )); } } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpener.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpener.java index a4d71fb9b..a15c5656e 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpener.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpener.java @@ -1,32 +1,25 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.asic.asice; import org.digidoc4j.Configuration; import org.digidoc4j.impl.asic.AsicSignature; -import org.digidoc4j.impl.asic.AsicSignatureOpener; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; import org.digidoc4j.impl.asic.xades.XadesSignature; -import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidator; -import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidatorFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** Class for converting Xades signature to ASiCE signature. */ -public class AsicESignatureOpener implements AsicSignatureOpener { - - private final static Logger logger = LoggerFactory.getLogger(AsicESignatureOpener.class); - private Configuration configuration; +public class AsicESignatureOpener extends AsicXadesSignatureOpener { /** * Constructor @@ -34,32 +27,12 @@ public class AsicESignatureOpener implements AsicSignatureOpener { * @param configuration configuration */ public AsicESignatureOpener(Configuration configuration) { - this.configuration = configuration; + super(configuration); } - /** - * Xades signature wrapper opening method. - * @param signatureWrapper wrapper containing signature document and it's xades signature - * @return ASiCE signature - */ @Override - public AsicSignature open(XadesSignatureWrapper signatureWrapper) { - logger.debug("Opening xades signature"); - return createAsicESignature(signatureWrapper); + protected AsicSignature createAsicSignature(XadesSignature xadesSignature, XadesSignatureValidator xadesValidator) { + return new AsicESignature(xadesSignature, xadesValidator); } - private AsicESignature createAsicESignature(XadesSignatureWrapper signatureWrapper) { - XadesSignatureValidator xadesValidator = createSignatureValidator(signatureWrapper.getSignature()); - AsicESignature asicESignature = new AsicESignature(signatureWrapper.getSignature(), xadesValidator); - asicESignature.setSignatureDocument(signatureWrapper.getSignatureDocument()); - return asicESignature; - } - - private XadesSignatureValidator createSignatureValidator(XadesSignature signature) { - XadesSignatureValidatorFactory validatorFactory = new XadesSignatureValidatorFactory(); - validatorFactory.setConfiguration(configuration); - validatorFactory.setSignature(signature); - XadesSignatureValidator xadesValidator = validatorFactory.create(); - return xadesValidator; - } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureBuilder.java deleted file mode 100644 index 7316c10a1..000000000 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureBuilder.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.digidoc4j.impl.asic.asice.bdoc; - -import org.digidoc4j.impl.asic.asice.AsicESignatureBuilder; - -/** - * Created by Andrei on 29.11.2017. - */ -public class BDocSignatureBuilder extends AsicESignatureBuilder { -} - diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureFinalizer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureFinalizer.java deleted file mode 100644 index 01cb7fd67..000000000 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureFinalizer.java +++ /dev/null @@ -1,60 +0,0 @@ -/* DigiDoc4J library - * - * This software is released under either the GNU Library General Public - * License (see LICENSE.LGPL). - * - * Note that the only valid version of the LGPL license as far as this - * project is concerned is the original GNU Library General Public License - * Version 2.1, February 1999 - */ - -package org.digidoc4j.impl.asic.asice.bdoc; - -import eu.europa.esig.dss.model.Policy; -import org.digidoc4j.Configuration; -import org.digidoc4j.DataFile; -import org.digidoc4j.SignatureParameters; -import org.digidoc4j.SignatureProfile; -import org.digidoc4j.impl.asic.asice.AsicESignatureFinalizer; -import org.digidoc4j.utils.PolicyUtils; - -import java.util.List; - -/** - * BDoc signature finalizer for datafiles signing process. - */ -public class BDocSignatureFinalizer extends AsicESignatureFinalizer { - - public BDocSignatureFinalizer(List dataFilesToSign, SignatureParameters signatureParameters, Configuration configuration) { - super(dataFilesToSign, signatureParameters, configuration); - } - - @Override - protected void setSignaturePolicy() { - if (isTimeMarkProfile() || isEpesProfile()) { - Policy signaturePolicy = determineSignaturePolicy(); - facade.setSignaturePolicy(signaturePolicy); - } - } - - @Override - protected void validateSignatureCompatibility() { - // Do nothing - } - - private Policy determineSignaturePolicy() { - Policy policyDefinedByUser = signatureParameters.getPolicy(); - if (policyDefinedByUser != null && PolicyUtils.areAllPolicyValuesDefined(policyDefinedByUser)) { - return policyDefinedByUser; - } - return PolicyUtils.createBDocSignaturePolicy(); - } - - private boolean isTimeMarkProfile() { - return SignatureProfile.LT_TM == signatureParameters.getSignatureProfile(); - } - - private boolean isEpesProfile() { - return SignatureProfile.B_EPES == signatureParameters.getSignatureProfile(); - } -} diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpener.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpener.java index 0692bc84a..b18026c1e 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpener.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpener.java @@ -1,63 +1,36 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.asic.asice.bdoc; import org.digidoc4j.Configuration; import org.digidoc4j.impl.asic.AsicSignature; -import org.digidoc4j.impl.asic.AsicSignatureOpener; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; import org.digidoc4j.impl.asic.xades.XadesSignature; -import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidator; -import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidatorFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * BDOC signature opener */ -public class BDocSignatureOpener implements AsicSignatureOpener { - - private final static Logger logger = LoggerFactory.getLogger(BDocSignatureOpener.class); - private Configuration configuration; +public class BDocSignatureOpener extends AsicXadesSignatureOpener { /** * @param configuration configuration */ public BDocSignatureOpener(Configuration configuration) { - this.configuration = configuration; + super(configuration); } - /** - * Xades signature wrapper opening method. - * @param signatureWrapper wrapper containing signature document and it's xades signature - * @return BDoc signature - */ @Override - public AsicSignature open(XadesSignatureWrapper signatureWrapper) { - logger.debug("Opening xades signature"); - return createBDocSignature(signatureWrapper); + protected AsicSignature createAsicSignature(XadesSignature xadesSignature, XadesSignatureValidator xadesValidator) { + return new BDocSignature(xadesSignature, xadesValidator); } - private BDocSignature createBDocSignature(XadesSignatureWrapper signatureWrapper) { - XadesSignatureValidator xadesValidator = createSignatureValidator(signatureWrapper.getSignature()); - BDocSignature bDocSignature = new BDocSignature(signatureWrapper.getSignature(), xadesValidator); - bDocSignature.setSignatureDocument(signatureWrapper.getSignatureDocument()); - return bDocSignature; - } - - private XadesSignatureValidator createSignatureValidator(XadesSignature signature) { - XadesSignatureValidatorFactory validatorFactory = new XadesSignatureValidatorFactory(); - validatorFactory.setConfiguration(configuration); - validatorFactory.setSignature(signature); - XadesSignatureValidator xadesValidator = validatorFactory.create(); - return xadesValidator; - } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSContainer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSContainer.java index fbe5b6a1a..a66f852c4 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSContainer.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSContainer.java @@ -19,7 +19,6 @@ import org.digidoc4j.impl.asic.AsicContainerCreator; import org.digidoc4j.impl.asic.AsicParseResult; import org.digidoc4j.impl.asic.AsicSignatureOpener; -import org.digidoc4j.impl.asic.asice.AsicESignatureOpener; import java.io.InputStream; import java.io.OutputStream; @@ -123,7 +122,7 @@ public void save(OutputStream out) { @Override protected AsicSignatureOpener getSignatureOpener() { - return new AsicESignatureOpener(getConfiguration()); + return new AsicSSignatureOpener(getConfiguration()); } /** diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureBuilder.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureBuilder.java new file mode 100644 index 000000000..ed6812902 --- /dev/null +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureBuilder.java @@ -0,0 +1,39 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asics; + +import org.apache.commons.lang3.StringUtils; +import org.digidoc4j.Container; +import org.digidoc4j.SignatureContainerMatcherValidator; +import org.digidoc4j.exceptions.IllegalSignatureProfileException; +import org.digidoc4j.impl.SignatureFinalizer; +import org.digidoc4j.impl.asic.AsicSignatureBuilder; + +public class AsicSSignatureBuilder extends AsicSignatureBuilder { + + @Override + protected SignatureFinalizer createSignatureFinalizer() { + return new AsicSSignatureFinalizer(container.getDataFiles(), signatureParameters, getConfiguration()); + } + + @Override + protected void validateSignatureCompatibilityWithContainer() { + if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile()) && isAsicSContainer()) { + throw new IllegalSignatureProfileException( + "Cannot add BDoc specific (" + signatureParameters.getSignatureProfile() + ") signature to ASiCS container"); + } + } + + private boolean isAsicSContainer() { + return container instanceof AsicSContainer && StringUtils.equals(Container.DocumentType.ASICS.name(), container.getType()); + } + +} diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureFinalizer.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureFinalizer.java new file mode 100644 index 000000000..2cf48e36a --- /dev/null +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureFinalizer.java @@ -0,0 +1,48 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asics; + +import org.digidoc4j.Configuration; +import org.digidoc4j.DataFile; +import org.digidoc4j.SignatureContainerMatcherValidator; +import org.digidoc4j.SignatureParameters; +import org.digidoc4j.exceptions.IllegalSignatureProfileException; +import org.digidoc4j.impl.asic.AsicSignature; +import org.digidoc4j.impl.asic.AsicSignatureFinalizer; +import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; + +import java.util.List; + +/** + * ASiCS signature finalizer for datafiles signing process. + */ +final class AsicSSignatureFinalizer extends AsicSignatureFinalizer { + + AsicSSignatureFinalizer(List dataFilesToSign, SignatureParameters signatureParameters, Configuration configuration) { + super(dataFilesToSign, signatureParameters, configuration); + } + + @Override + protected AsicSignature asAsicSignature(XadesSignatureWrapper signatureWrapper) { + return new AsicSSignatureOpener(configuration).open(signatureWrapper); + } + + @Override + protected void validateSignatureCompatibility() { + if (SignatureContainerMatcherValidator.isBDocOnlySignature(signatureParameters.getSignatureProfile())) { + throw new IllegalSignatureProfileException(String.format( + "Cannot create BDoc specific (%s) signature", + signatureParameters.getSignatureProfile() + )); + } + } + +} diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpener.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpener.java new file mode 100644 index 000000000..56a8b4f78 --- /dev/null +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpener.java @@ -0,0 +1,38 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asics; + +import org.digidoc4j.Configuration; +import org.digidoc4j.impl.asic.AsicSignature; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; +import org.digidoc4j.impl.asic.xades.XadesSignature; +import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidator; + +/** + * Class for converting XAdES signature to ASiC-S signature. + */ +public class AsicSSignatureOpener extends AsicXadesSignatureOpener { + + /** + * Creates an instance of ASiC signature opener + * + * @param configuration configuration + */ + public AsicSSignatureOpener(Configuration configuration) { + super(configuration); + } + + @Override + protected AsicSignature createAsicSignature(XadesSignature xadesSignature, XadesSignatureValidator xadesValidator) { + return new AsicSSignature(xadesSignature, xadesValidator); + } + +} diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestValidator.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestValidator.java index 667a665ed..b03de19c8 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestValidator.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/manifest/ManifestValidator.java @@ -15,8 +15,7 @@ import org.apache.xml.security.signature.Reference; import org.digidoc4j.Signature; import org.digidoc4j.exceptions.DigiDoc4JException; -import org.digidoc4j.impl.asic.asice.AsicESignature; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; +import org.digidoc4j.impl.asic.AsicSignature; import org.digidoc4j.impl.asic.xades.XadesSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -171,12 +170,7 @@ private Set getFileNamesFromManifestEntrySet(Set signatur private Set getSignatureEntries(Signature signature) { Set signatureEntries = new HashSet<>(); - XadesSignature origin; - if (signature.getClass() == BDocSignature.class) { - origin = ((BDocSignature) signature).getOrigin(); - } else { - origin = ((AsicESignature) signature).getOrigin(); - } + XadesSignature origin = ((AsicSignature) signature).getOrigin(); List references = origin.getReferences(); for (Reference reference : references) { if (reference.getType().equals("")) { diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpener.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpener.java new file mode 100644 index 000000000..6da9e58a1 --- /dev/null +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpener.java @@ -0,0 +1,64 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.xades; + +import org.digidoc4j.Configuration; +import org.digidoc4j.impl.asic.AsicSignature; +import org.digidoc4j.impl.asic.AsicSignatureOpener; +import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidator; +import org.digidoc4j.impl.asic.xades.validation.XadesSignatureValidatorFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Objects; + +/** + * Base class for converting XAdES signature to ASiC signature. + */ +public abstract class AsicXadesSignatureOpener implements AsicSignatureOpener { + + private final static Logger LOGGER = LoggerFactory.getLogger(AsicXadesSignatureOpener.class); + + protected final Configuration configuration; + + /** + * Creates an instance of ASiC signature opener + * + * @param configuration configuration + */ + protected AsicXadesSignatureOpener(Configuration configuration) { + this.configuration = Objects.requireNonNull(configuration); + } + + /** + * XAdES signature wrapper opening method. + * @param signatureWrapper wrapper containing signature document and its XAdES signature + * @return ASiC signature + */ + @Override + public AsicSignature open(XadesSignatureWrapper signatureWrapper) { + LOGGER.debug("Opening XAdES signature"); + XadesSignatureValidator xadesValidator = createSignatureValidator(signatureWrapper.getSignature()); + AsicSignature asicSignature = createAsicSignature(signatureWrapper.getSignature(), xadesValidator); + asicSignature.setSignatureDocument(signatureWrapper.getSignatureDocument()); + return asicSignature; + } + + protected abstract AsicSignature createAsicSignature(XadesSignature xadesSignature, XadesSignatureValidator xadesValidator); + + private XadesSignatureValidator createSignatureValidator(XadesSignature signature) { + XadesSignatureValidatorFactory validatorFactory = new XadesSignatureValidatorFactory(); + validatorFactory.setConfiguration(configuration); + validatorFactory.setSignature(signature); + return validatorFactory.create(); + } + +} diff --git a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/SignatureExtender.java b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/SignatureExtender.java index 909a0d13e..36d88a77d 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/SignatureExtender.java +++ b/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/SignatureExtender.java @@ -1,18 +1,17 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.asic.xades; import eu.europa.esig.dss.enumerations.SignatureLevel; import eu.europa.esig.dss.model.DSSDocument; -import eu.europa.esig.dss.model.Policy; import eu.europa.esig.dss.service.tsp.OnlineTSPSource; import eu.europa.esig.dss.spi.client.http.DataLoader; import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPSource; @@ -24,12 +23,10 @@ import org.digidoc4j.impl.AiaSourceFactory; import org.digidoc4j.impl.TspDataLoaderFactory; import org.digidoc4j.impl.asic.AsicSignature; -import org.digidoc4j.utils.PolicyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -37,6 +34,8 @@ import java.util.Set; import static java.util.Arrays.asList; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.digidoc4j.SignatureProfile.B_BES; import static org.digidoc4j.SignatureProfile.B_EPES; @@ -48,23 +47,21 @@ public class SignatureExtender { private static final Logger logger = LoggerFactory.getLogger(SignatureExtender.class); private static final Map> possibleExtensions = new HashMap<>(5); - private Configuration configuration; - private DSSDocument detachedContent; - private List detachedContents; - private XadesSigningDssFacade extendingFacade; + + private final Configuration configuration; + private final List detachedContents; + private final XadesSigningDssFacade extendingFacade; static { possibleExtensions.put(B_BES, new HashSet<>(asList(LT, LTA))); - possibleExtensions.put(B_EPES, new HashSet<>(singletonList(LT_TM))); - possibleExtensions.put(LT, new HashSet<>(singletonList(LTA))); - possibleExtensions.put(LT_TM, Collections.emptySet()); - possibleExtensions.put(LTA, Collections.emptySet()); + possibleExtensions.put(B_EPES, emptySet()); + possibleExtensions.put(LT, singleton(LTA)); + possibleExtensions.put(LT_TM, emptySet()); + possibleExtensions.put(LTA, emptySet()); } public SignatureExtender(Configuration configuration, DSSDocument detachedContent) { - this.configuration = configuration; - this.detachedContent = detachedContent; - extendingFacade = new XadesSigningDssFacade(); + this(configuration, singletonList(detachedContent)); } public SignatureExtender(Configuration configuration, List detachedContent) { @@ -74,7 +71,7 @@ public SignatureExtender(Configuration configuration, List detached } public List extend(List signaturesToExtend, SignatureProfile profile) { - logger.debug("Extending signatures to " + profile); + logger.debug("Extending signatures to {}", profile); validatePossibilityToExtendTo(signaturesToExtend, profile); prepareExtendingFacade(profile); List extendedSignatures = new ArrayList<>(); @@ -92,7 +89,6 @@ private void prepareExtendingFacade(SignatureProfile profile) { extendingFacade.setTspSource(tspSource); SignatureLevel signatureLevel = getSignatureLevel(profile); extendingFacade.setSignatureLevel(signatureLevel); - setSignaturePolicy(profile); extendingFacade.setAiaSource(new AiaSourceFactory(configuration).create()); } @@ -116,28 +112,21 @@ private OnlineTSPSource createTimeStampProviderSource() { } private SignatureLevel getSignatureLevel(SignatureProfile profile) { - if (profile == SignatureProfile.LT || profile == SignatureProfile.LT_TM) { + if (profile == SignatureProfile.LT) { return SignatureLevel.XAdES_BASELINE_LT; } if (profile == SignatureProfile.LTA) { return SignatureLevel.XAdES_BASELINE_LTA; } - logger.error("Extending signature to " + profile + " is not supported"); + logger.error("Extending signature to {} is not supported", profile); throw new NotSupportedException("Extending signature to " + profile + " is not supported"); } - private void setSignaturePolicy(SignatureProfile profile) { - if (profile == LT_TM) { - Policy signaturePolicy = PolicyUtils.createBDocSignaturePolicy(); - extendingFacade.setSignaturePolicy(signaturePolicy); - } - } - private void validatePossibilityToExtendTo(List signatures, SignatureProfile profile) { - logger.debug("Validating if it's possible to extend all the signatures to " + profile); + logger.debug("Validating if it's possible to extend all the signatures to {}", profile); for (Signature signature : signatures) { if (!canExtendSignatureToProfile(signature, profile)) { - String message = "It is not possible to extend " + signature.getProfile() + " signature to " + signature.getProfile() + "."; + String message = "It is not possible to extend " + signature.getProfile() + " signature to " + profile + "."; logger.error(message); throw new NotSupportedException(message); } @@ -145,6 +134,6 @@ private void validatePossibilityToExtendTo(List signatures, Signature } private boolean canExtendSignatureToProfile(Signature signature, SignatureProfile profile) { - return possibleExtensions.get(signature.getProfile()).contains(profile); + return possibleExtensions.getOrDefault(signature.getProfile(), emptySet()).contains(profile); } } diff --git a/digidoc4j/src/main/java/org/digidoc4j/utils/PolicyUtils.java b/digidoc4j/src/main/java/org/digidoc4j/utils/PolicyUtils.java index 1fa0b420f..cc5b35554 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/utils/PolicyUtils.java +++ b/digidoc4j/src/main/java/org/digidoc4j/utils/PolicyUtils.java @@ -25,6 +25,7 @@ public final class PolicyUtils { * * @return Policy */ + @Deprecated public static Policy createBDocSignaturePolicy() { Policy signaturePolicy = new Policy(); signaturePolicy.setId("urn:oid:" + TmSignaturePolicyType.BDOC_2_1_0.getOid()); diff --git a/digidoc4j/src/test/java/org/digidoc4j/AbstractTest.java b/digidoc4j/src/test/java/org/digidoc4j/AbstractTest.java index c5809beec..38921026b 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/AbstractTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/AbstractTest.java @@ -68,8 +68,11 @@ import java.nio.file.Paths; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.time.Duration; +import java.time.Instant; import java.util.Arrays; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Objects; import java.util.function.Consumer; @@ -78,6 +81,9 @@ import static org.digidoc4j.Container.DocumentType.ASICS; import static org.digidoc4j.Container.DocumentType.BDOC; import static org.digidoc4j.Container.DocumentType.DDOC; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.lessThanOrEqualTo; /** * @author Janar Rahumeel (CGI Estonia) @@ -437,8 +443,7 @@ protected T createSignatureBy(DigestAlgorithm digestAlgorithm, SignatureToke protected String createSignedContainerBy(Container.DocumentType type, String extension) { String file = this.getFileBy(extension); Container container = this.createNonEmptyContainerBy(type, Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - SignatureProfile signatureProfile = (type == BDOC) ? SignatureProfile.LT_TM : SignatureProfile.LT; - createSignatureBy(container, signatureProfile, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); container.saveAsFile(file); return file; } @@ -638,6 +643,23 @@ protected static void assertSignatureWith(Signature signature, Consumer errors = validationResult.getErrors(); Assert.assertEquals(validationResult.isValid(), CollectionUtils.isEmpty(errors)); diff --git a/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java b/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java index 20c18aae3..2859b4445 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java @@ -2,6 +2,7 @@ import org.junit.Ignore; import org.junit.Test; + import java.io.File; import static org.junit.Assert.assertEquals; @@ -20,7 +21,7 @@ public void signAsiceContainerWithoutAiaOcsp() { .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12SignatureToken); + this.createSignatureBy(container, pkcs12SignatureToken); assertTrue(container.validate().isValid()); assertEquals("EMAILADDRESS=pki@sk.ee, CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); } @@ -34,25 +35,11 @@ public void signAsiceContainerUsingAiaOcsp() { .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12SignatureToken); + this.createSignatureBy(container, pkcs12SignatureToken); assertTrue(container.validate().isValid()); assertEquals("C=EE, O=SK ID Solutions AS, OU=OCSP, CN=DEMO of ESTEID-SK 2015 AIA OCSP RESPONDER 2018", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); } - @Test - public void bdocContainerIgnoresAiaOcsp() { - Configuration configuration = new Configuration(Configuration.Mode.TEST); - configuration.setPreferAiaOcsp(true); - File testFile1 = this.createTemporaryFileBy("testFile.txt", "TEST"); - Container container = ContainerBuilder.aContainer(Container.DocumentType.BDOC) - .withDataFile(testFile1.getPath(), "text/plain") - .withConfiguration(configuration) - .build(); - this.createSignatureBy(container, SignatureProfile.LT_TM, this.pkcs12SignatureToken); - assertTrue(container.validate().isValid()); - assertEquals("EMAILADDRESS=pki@sk.ee, CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); - } - @Test public void signAsiceContainerWithEccTokenUsingAiaOcsp() { Configuration configuration = new Configuration(Configuration.Mode.TEST); @@ -62,7 +49,7 @@ public void signAsiceContainerWithEccTokenUsingAiaOcsp() { .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12EccSignatureToken); + this.createSignatureBy(container, pkcs12EccSignatureToken); assertTrue(container.validate().isValid()); assertEquals("C=EE, O=SK ID Solutions AS, OU=OCSP, CN=DEMO of ESTEID-SK 2015 AIA OCSP RESPONDER 2018", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); } @@ -76,7 +63,7 @@ public void signAsiceContainerWithEsteid2018UsingAiaOcsp() { .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12Esteid2018SignatureToken); + this.createSignatureBy(container, pkcs12Esteid2018SignatureToken); assertTrue(container.validate().isValid()); assertEquals("C=EE, O=SK ID Solutions AS, OU=OCSP, CN=DEMO of ESTEID-SK 2018 AIA OCSP RESPONDER 2018", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); } @@ -93,7 +80,7 @@ public void signAsiceContainerWithManuallyConfiguredAiaOcsp() { .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12SignatureToken); + this.createSignatureBy(container, pkcs12SignatureToken); assertTrue(container.validate().isValid()); assertEquals("C=EE, O=SK ID Solutions AS, OU=OCSP, CN=DEMO of ESTEID-SK 2015 AIA OCSP RESPONDER 2018", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); } @@ -110,7 +97,7 @@ public void signAsiceContainerWithManuallyConfiguredOlderAiaOcsp_whileUsingOcspN .withDataFile(testFile1.getPath(), "text/plain") .withConfiguration(configuration) .build(); - this.createSignatureBy(container, this.pkcs12SignatureToken); + this.createSignatureBy(container, pkcs12SignatureToken); ValidationResult result = container.validate(); assertFalse(result.isValid()); assertTrue(result.getErrors().get(0).getMessage().contains("No revocation data for the certificate")); diff --git a/digidoc4j/src/test/java/org/digidoc4j/DetachedXadesSignatureBuilderTest.java b/digidoc4j/src/test/java/org/digidoc4j/DetachedXadesSignatureBuilderTest.java index ecc8d5f91..d9a679540 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/DetachedXadesSignatureBuilderTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/DetachedXadesSignatureBuilderTest.java @@ -10,10 +10,6 @@ package org.digidoc4j; -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; - import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.SerializationUtils; import org.digidoc4j.exceptions.InvalidDataFileException; @@ -21,11 +17,20 @@ import org.digidoc4j.exceptions.NotSupportedException; import org.digidoc4j.exceptions.SignatureTokenMissingException; import org.digidoc4j.exceptions.SignerCertificateRequiredException; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; import org.digidoc4j.test.TestAssert; import org.junit.Assert; import org.junit.Test; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.startsWith; + public class DetachedXadesSignatureBuilderTest extends AbstractTest { @Test @@ -33,10 +38,11 @@ public void signExternally() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()) - .buildDataToSign(); + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()) + .buildDataToSign(); byte[] serializedDataToSign = SerializationUtils.serialize(dataToSign); DataToSign deserializedDataToSign = SerializationUtils.deserialize(serializedDataToSign); @@ -52,10 +58,11 @@ public void signWithSignatureToken() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigning(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSignatureToken(pkcs12EccSignatureToken) + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); @@ -66,10 +73,11 @@ public void signWithRSASignatureToken() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12SignatureToken) - .invokeSigningProcess(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSignatureToken(pkcs12SignatureToken) + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); @@ -83,11 +91,12 @@ public void signWithMultipleDataFiles() throws Exception { byte[] digest2 = MessageDigest.getInstance("SHA-256").digest("hello2".getBytes()); DigestDataFile digestDataFile2 = new DigestDataFile("hello2.txt", DigestAlgorithm.SHA256, digest2, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withDataFile(digestDataFile2) - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigning(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withDataFile(digestDataFile2) + .withSignatureToken(pkcs12EccSignatureToken) + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); @@ -97,83 +106,132 @@ public void signWithMultipleDataFiles() throws Exception { public void signWithNormalDataFile() { DataFile dataFile = new DataFile("hello".getBytes(), "hello.txt", "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigning(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile) + .withSignatureToken(pkcs12EccSignatureToken) + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); } - @Test(expected = InvalidDataFileException.class) + @Test public void invokeSigningWithEmptyDataFileThrowsException() { DataFile dataFile = new DataFile(new byte[0], "hello.txt", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigning(); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile) + .withSignatureToken(pkcs12EccSignatureToken); + + InvalidDataFileException caughtException = assertThrows( + InvalidDataFileException.class, + signatureBuilder::invokeSigning + ); + + assertThat(caughtException.getMessage(), startsWith("Cannot sign empty datafile")); } - @Test(expected = InvalidDataFileException.class) + @Test public void buildDataToSignWithEmptyDataFileThrowsException() { DataFile dataFile = new DataFile(new byte[0], "hello.txt", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigning(); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile) + .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()); + + InvalidDataFileException caughtException = assertThrows( + InvalidDataFileException.class, + signatureBuilder::buildDataToSign + ); + + assertThat(caughtException.getMessage(), startsWith("Cannot sign empty datafile")); } - @Test(expected = SignatureTokenMissingException.class) + @Test public void invokeSigningWithoutSignatureTokenThrowsException() { DataFile dataFile = new DataFile("hello".getBytes(), "hello.txt", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .invokeSigning(); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile); + + SignatureTokenMissingException caughtException = assertThrows( + SignatureTokenMissingException.class, + signatureBuilder::invokeSigning + ); + + assertThat(caughtException.getMessage(), nullValue()); } - @Test(expected = SignerCertificateRequiredException.class) + @Test public void buildDataToSignWithoutSignatureTokenThrowsException() { DataFile dataFile = new DataFile("hello".getBytes(), "hello.txt", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .buildDataToSign(); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile); + + SignerCertificateRequiredException caughtException = assertThrows( + SignerCertificateRequiredException.class, + signatureBuilder::buildDataToSign + ); + + assertThat(caughtException.getMessage(), nullValue()); } - @Test(expected = InvalidSignatureException.class) + @Test public void openAdESSignatureWithoutSignatureDocumentThrowsException() { DataFile dataFile = new DataFile("hello".getBytes(), "hello.txt", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .openAdESSignature(null); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile); + + InvalidSignatureException caughtException = assertThrows( + InvalidSignatureException.class, + () -> signatureBuilder.openAdESSignature(null) + ); + + assertThat(caughtException.getMessage(), equalTo("Invalid signature document")); } @Test - public void signWithLT_TMProfile() throws Exception { - byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); - DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); + public void usingLT_TMProfileNotAllowed() { + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .withSignatureProfile(SignatureProfile.LT_TM) - .invokeSigningProcess(); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); - assertTimemarkSignature(signature); - assertValidSignature(signature); + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); + } + + @Test + public void usingB_EPESProfileNotAllowed() { + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); } @Test - public void signWithB_EPESProfile() throws Exception { + public void signWithB_BESProfile() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .withSignatureProfile(SignatureProfile.B_EPES) - .invokeSigningProcess(); - assertBEpesSignature(signature); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSignatureToken(pkcs12EccSignatureToken) + .withSignatureProfile(SignatureProfile.B_BES) + .invokeSigning(); + + assertBBesSignature(signature); ValidationResult validationResult = signature.validateSignature(); Assert.assertFalse(validationResult.isValid()); TestAssert.assertContainsExactSetOfErrors(validationResult.getWarnings(), @@ -183,7 +241,6 @@ public void signWithB_EPESProfile() throws Exception { "The certificate validation is not conclusive!", "No revocation data found for the certificate!" ); - } @Test @@ -191,25 +248,36 @@ public void signWithLTProfile() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .withSignatureProfile(SignatureProfile.LT) - .invokeSigningProcess(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSignatureToken(pkcs12EccSignatureToken) + .withSignatureProfile(SignatureProfile.LT) + .invokeSigning(); + assertTimestampSignature(signature); assertValidSignature(signature); } - @Test(expected = IllegalArgumentException.class) - public void signWithLTAProfile() throws Exception { + @Test + public void signWithLTAProfileNotAllowed() throws Exception { byte[] digest = MessageDigest.getInstance("SHA-256").digest("hello".getBytes()); DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .withSignatureToken(pkcs12EccSignatureToken) - .withSignatureProfile(SignatureProfile.LTA) - .invokeSigningProcess(); + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .withSignatureToken(pkcs12EccSignatureToken) + .withSignatureProfile(SignatureProfile.LTA); + + IllegalArgumentException caughtException = assertThrows( + IllegalArgumentException.class, + signatureBuilder::invokeSigning + ); + + assertThat(caughtException.getMessage(), equalTo( + "XAdES-LTA requires complete binaries of signed documents! Extension with a DigestDocument is not possible." + )); } @Test @@ -218,17 +286,19 @@ public void signWithSignerInfo() throws Exception { DigestDataFile digestDataFile1 = new DigestDataFile("hello1.txt", DigestAlgorithm.SHA256, digest, "text/plain"); DigestDataFile digestDataFile2 = new DigestDataFile("hello2.txt", DigestAlgorithm.SHA256, digest, "text/plain"); - Signature signature = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(digestDataFile1) - .withDataFile(digestDataFile2) - .withCity("myCity") - .withStateOrProvince("myStateOrProvince") - .withPostalCode("myPostalCode") - .withCountry("myCountry") - .withRoles("myRole / myResolution") - .withSignatureId("SIGNATURE-1") - .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigningProcess(); + Signature signature = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile1) + .withDataFile(digestDataFile2) + .withCity("myCity") + .withStateOrProvince("myStateOrProvince") + .withPostalCode("myPostalCode") + .withCountry("myCountry") + .withRoles("myRole / myResolution") + .withSignatureId("SIGNATURE-1") + .withSignatureToken(pkcs12EccSignatureToken) + .invokeSigning(); + Assert.assertTrue(signature.validateSignature().isValid()); Assert.assertEquals("myCity", signature.getCity()); Assert.assertEquals("myStateOrProvince", signature.getStateOrProvince()); @@ -250,55 +320,65 @@ public void readExistingSignatureAndValidate() throws Exception { DigestDataFile digestDataFile = new DigestDataFile("hello.txt", DigestAlgorithm.SHA256, digest, "text/plain"); Signature signature = DetachedXadesSignatureBuilder - .withConfiguration(new Configuration()) - .withDataFile(digestDataFile) - .openAdESSignature(xadesSignature); + .withConfiguration(new Configuration()) + .withDataFile(digestDataFile) + .openAdESSignature(xadesSignature); assertTimestampSignature(signature); assertValidSignatureWithWarnings(signature); } @Test - public void customSignaturePolicyAllowedForLT_TMSignatureProfile_resultsWithLTProfileBDocSignature() { - DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); - - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); + public void usingCustomSignaturePolicy_WhenSignatureProfileNotSet_NotSupported() { + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()); - Assert.assertNotNull(signature); - Assert.assertTrue(signature instanceof BDocSignature); - Assert.assertEquals(SignatureProfile.LT, signature.getProfile()); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } @Test - public void customSignaturePolicyWhenSignatureProfileNotSet_resultsWithTimestampSignature() { - DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); + public void usingCustomSignaturePolicy_WhenSignatureProfileIsB_BES_NotSupported() { + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withSignatureProfile(SignatureProfile.B_BES); - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); - assertTimestampSignature(signature); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void usingCustomSignaturePolicy_WhenSignatureProfileIsLT_NotSupported() { + DetachedXadesSignatureBuilder signatureBuilder = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } @Test public void encryptionMethodECDSA() { DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()) - .withOwnSignaturePolicy(validCustomPolicy()) - .withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA) - .buildDataToSign(); + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(new Configuration()) + .withDataFile(dataFile) + .withSignatureProfile(SignatureProfile.LT) + .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()) + .withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA) + .buildDataToSign(); Assert.assertEquals(EncryptionAlgorithm.ECDSA, dataToSign.getSignatureParameters().getEncryptionAlgorithm()); byte[] signatureValue = pkcs12EccSignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); @@ -306,37 +386,17 @@ public void encryptionMethodECDSA() { assertTimestampSignature(signature); } - @Test(expected = NotSupportedException.class) - public void signatureProfileLTNotAllowedForCustomSignaturePolicy() { - DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withOwnSignaturePolicy(validCustomPolicy()) - .withSignatureProfile(SignatureProfile.LT) - .buildDataToSign(); - } - - @Test(expected = NotSupportedException.class) - public void customSignaturePolicyNotAllowedForLTSignatureProfile() { - DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); - DetachedXadesSignatureBuilder.withConfiguration(new Configuration()) - .withDataFile(dataFile) - .withSignatureProfile(SignatureProfile.LT) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); - } - @Test public void signWithoutAssigningProfile_defaultPofileIsUsed_shouldSucceedWithTimestampSignature() { DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); Configuration configuration = new Configuration(); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(configuration) - .withDataFile(dataFile) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) - .buildDataToSign(); + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(configuration) + .withDataFile(dataFile) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()) + .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) + .buildDataToSign(); Signature signature = dataToSign.finalize(pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign())); Assert.assertSame(Constant.Default.SIGNATURE_PROFILE, signature.getProfile()); @@ -349,7 +409,8 @@ public void signWith256EcKey_withoutAssigningSignatureDigestAlgo_sha256Signature DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); Configuration configuration = new Configuration(); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(configuration) + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(configuration) .withDataFile(dataFile) .withSigningCertificate(pkcs12EccSignatureToken.getCertificate()) .buildDataToSign(); @@ -364,7 +425,8 @@ public void signWith384EcKey_withoutAssigningSignatureDigestAlgo_sha384Signature DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); Configuration configuration = new Configuration(); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(configuration) + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(configuration) .withDataFile(dataFile) .withSigningCertificate(pkcs12Esteid2018SignatureToken.getCertificate()) .buildDataToSign(); @@ -379,12 +441,14 @@ public void signWithDifferentDataFileAndSignatureDigestAlgorithm() { DataFile dataFile = new DataFile("something".getBytes(StandardCharsets.UTF_8), "filename", "text/plain"); Configuration configuration = new Configuration(); - DataToSign dataToSign = DetachedXadesSignatureBuilder.withConfiguration(configuration) + DataToSign dataToSign = DetachedXadesSignatureBuilder + .withConfiguration(configuration) .withSignatureDigestAlgorithm(DigestAlgorithm.SHA384) .withDataFileDigestAlgorithm(DigestAlgorithm.SHA512) .withDataFile(dataFile) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) .buildDataToSign(); + SignatureParameters signatureParameters = dataToSign.getSignatureParameters(); Assert.assertEquals(DigestAlgorithm.SHA384, signatureParameters.getSignatureDigestAlgorithm()); Assert.assertEquals(DigestAlgorithm.SHA512, signatureParameters.getDataFileDigestAlgorithm()); @@ -402,7 +466,7 @@ public void mimeTypeValueNotValidated() throws Exception { .withConfiguration(new Configuration()) .withDataFile(digestDataFile) .withSignatureToken(pkcs12EccSignatureToken) - .invokeSigningProcess(); + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); @@ -420,7 +484,7 @@ public void addDetachedSignatureToContainer() throws Exception { .withDataFile(digestDataFile) .withSignatureToken(pkcs12EccSignatureToken) .withSignatureProfile(SignatureProfile.LT) - .invokeSigningProcess(); + .invokeSigning(); assertTimestampSignature(signature); assertValidSignature(signature); diff --git a/digidoc4j/src/test/java/org/digidoc4j/SignatureBuilderTest.java b/digidoc4j/src/test/java/org/digidoc4j/SignatureBuilderTest.java index 0bdde6494..8635c30e3 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/SignatureBuilderTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/SignatureBuilderTest.java @@ -10,19 +10,12 @@ package org.digidoc4j; -import eu.europa.esig.dss.validation.timestamp.TimestampToken; -import eu.europa.esig.dss.validation.SignaturePolicy; import org.apache.commons.io.FileUtils; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.digidoc4j.exceptions.IllegalSignatureProfileException; -import org.digidoc4j.exceptions.ServiceUnreachableException; import org.digidoc4j.exceptions.InvalidSignatureException; import org.digidoc4j.exceptions.NotSupportedException; +import org.digidoc4j.exceptions.ServiceUnreachableException; import org.digidoc4j.exceptions.SignatureTokenMissingException; -import org.digidoc4j.impl.asic.asice.AsicESignature; -import org.digidoc4j.impl.asic.asice.bdoc.BDocContainerBuilder; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; -import org.digidoc4j.signers.PKCS12SignatureToken; +import org.digidoc4j.impl.asic.report.SignatureValidationReport; import org.digidoc4j.test.CustomContainer; import org.digidoc4j.test.MockSignatureBuilder; import org.digidoc4j.test.TestAssert; @@ -38,24 +31,87 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; -import java.security.Security; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; import static org.digidoc4j.Configuration.Mode.TEST; import static org.digidoc4j.Container.DocumentType.ASICE; +import static org.digidoc4j.Container.DocumentType.ASICS; import static org.digidoc4j.Container.DocumentType.BDOC; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.fail; public class SignatureBuilderTest extends AbstractTest { @Test - public void buildingDataToSign_shouldReturnDataToSign() throws Exception { - Container container = this.createNonEmptyContainer(); - SignatureBuilder builder = SignatureBuilder.aSignature(container). - withSigningCertificate(pkcs12SignatureToken.getCertificate()); - DataToSign dataToSign = builder.buildDataToSign(); + public void aSignature_WhenContainerTypeIsDDOC_ThrowsNotSupportedException() { + Container container = ContainerOpener.open(DDOC_TEST_FILE); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureBuilder.aSignature(container) + ); + + assertThat(caughtException.getMessage(), containsString("Unknown container type: DDOC")); + } + + @Test + public void aSignature_WhenContainerTypeIsPADES_ThrowsNotSupportedException() { + Container container = ContainerOpener + .open("src/test/resources/testFiles/invalid-containers/hello_signed_INCSAVE_signed_EDITED.pdf"); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureBuilder.aSignature(container) + ); + + assertThat(caughtException.getMessage(), containsString("Unknown container type: PADES")); + } + + @Test + public void buildDataToSign_WhenContainerTypeIsASiCE_ReturnsDataToSign() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICE)) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()); + + DataToSign dataToSign = signatureBuilder.buildDataToSign(); + + Assert.assertNotNull(dataToSign); + Assert.assertNotNull(dataToSign.getDataToSign()); + Assert.assertNotNull(dataToSign.getSignatureParameters()); + Assert.assertEquals(DigestAlgorithm.SHA256, dataToSign.getDigestAlgorithm()); + } + + @Test + public void buildDataToSign_WhenContainerTypeIsBDOC_ReturnsDataToSign() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(BDOC)) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()); + + DataToSign dataToSign = signatureBuilder.buildDataToSign(); + + Assert.assertNotNull(dataToSign); + Assert.assertNotNull(dataToSign.getDataToSign()); + Assert.assertNotNull(dataToSign.getSignatureParameters()); + Assert.assertEquals(DigestAlgorithm.SHA256, dataToSign.getDigestAlgorithm()); + } + + @Test + public void buildDataToSign_WhenContainerTypeIsASiCS_ReturnsDataToSign() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICS)) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()); + + DataToSign dataToSign = signatureBuilder.buildDataToSign(); + Assert.assertNotNull(dataToSign); Assert.assertNotNull(dataToSign.getDataToSign()); Assert.assertNotNull(dataToSign.getSignatureParameters()); @@ -63,52 +119,138 @@ public void buildingDataToSign_shouldReturnDataToSign() throws Exception { } @Test - public void buildingDataToSign_shouldContainSignatureParameters() throws Exception { - Container container = this.createNonEmptyContainer(); - SignatureBuilder builder = SignatureBuilder.aSignature(container).withCity("San Pedro"). - withStateOrProvince("Puerto Vallarta").withPostalCode("13456").withCountry("Val Verde"). - withRoles("Manager", "Suspicious Fisherman").withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).withSignatureId("S0"). - withSigningCertificate(pkcs12SignatureToken.getCertificate()); - DataToSign dataToSign = builder.buildDataToSign(); + public void buildDataToSign_WhenSignatureParametersAreProvided_ReturnsDataToSignContainingSignatureParameters() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICE)) + .withCity("San Pedro") + .withStateOrProvince("Puerto Vallarta") + .withPostalCode("13456") + .withCountry("Val Verde") + .withRoles("Manager", "Suspicious Fisherman") + .withDataFileDigestAlgorithm(DigestAlgorithm.SHA512) + .withSignatureDigestAlgorithm(DigestAlgorithm.SHA384) + .withSignatureProfile(SignatureProfile.LTA) + .withSignatureId("S0") + .withSigningCertificate(pkcs12SignatureToken.getCertificate()); + + DataToSign dataToSign = signatureBuilder.buildDataToSign(); + SignatureParameters parameters = dataToSign.getSignatureParameters(); Assert.assertEquals("San Pedro", parameters.getCity()); Assert.assertEquals("Puerto Vallarta", parameters.getStateOrProvince()); Assert.assertEquals("13456", parameters.getPostalCode()); Assert.assertEquals("Val Verde", parameters.getCountry()); Assert.assertEquals("Manager", parameters.getRoles().get(0)); - Assert.assertEquals(DigestAlgorithm.SHA256, parameters.getSignatureDigestAlgorithm()); - Assert.assertEquals(SignatureProfile.LT_TM, parameters.getSignatureProfile()); + Assert.assertEquals(DigestAlgorithm.SHA512, parameters.getDataFileDigestAlgorithm()); + Assert.assertEquals(DigestAlgorithm.SHA384, parameters.getSignatureDigestAlgorithm()); + Assert.assertEquals(SignatureProfile.LTA, parameters.getSignatureProfile()); Assert.assertEquals("S0", parameters.getSignatureId()); Assert.assertSame(pkcs12SignatureToken.getCertificate(), parameters.getSigningCertificate()); byte[] bytesToSign = dataToSign.getDataToSign(); Assert.assertNotNull(bytesToSign); - Assert.assertTrue(bytesToSign.length > 1); + assertThat(bytesToSign.length, greaterThan(1)); } @Test - public void signDocumentExternallyTwice() throws Exception { - Container container = this.createNonEmptyContainer(); + public void signDocumentExternallyTwice() { + Container container = createNonEmptyContainer(); + DataToSign dataToSign = TestDataBuilderUtil.buildDataToSign(container, "S0"); Signature signature = TestDataBuilderUtil.makeSignature(container, dataToSign); - this.assertSignatureIsValid(signature, SignatureProfile.LT); + assertSignatureIsValid(signature, SignatureProfile.LT); + DataToSign dataToSign2 = TestDataBuilderUtil.buildDataToSign(container, "S1"); Signature signature2 = TestDataBuilderUtil.makeSignature(container, dataToSign2); - this.assertSignatureIsValid(signature2, SignatureProfile.LT); - container.saveAsFile(this.getFileBy("asice")); + assertSignatureIsValid(signature2, SignatureProfile.LT); + + ContainerValidationResult validationResult = container.validate(); + TestAssert.assertContainerIsValid(validationResult); + List reports = validationResult.getReports(); + assertThat(reports, hasSize(2)); + assertThat(reports.get(0).getId(), equalTo("S0")); + assertThat(reports.get(1).getId(), equalTo("S1")); + } + + @Test + public void invokeSigning_WhenContainerTypeIsASiCE_Signature() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICE)) + .withSignatureToken(pkcs12SignatureToken); + + Signature signature = signatureBuilder.invokeSigning(); + + Assert.assertNotNull(signature); + assertSignatureIsValid(signature, SignatureProfile.LT); + } + + @Test + public void invokeSigning_WhenContainerTypeIsBDOC_Signature() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(BDOC)) + .withSignatureToken(pkcs12SignatureToken); + + Signature signature = signatureBuilder.invokeSigning(); + + Assert.assertNotNull(signature); + assertSignatureIsValid(signature, SignatureProfile.LT); + } + + @Test + public void invokeSigning_WhenContainerTypeIsASiCS_Signature() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICS)) + .withSignatureToken(pkcs12SignatureToken); + + Signature signature = signatureBuilder.invokeSigning(); + + Assert.assertNotNull(signature); + assertSignatureIsValid(signature, SignatureProfile.LT); + } + + @Test + public void invokeSigning_WhenSignatureParametersAreProvided_ReturnsDataToSignContainingSignatureParameters() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(ASICE)) + .withCity("Tallinn") + .withStateOrProvince("Harjumaa") + .withPostalCode("13456") + .withCountry("Estonia") + .withRoles("Manager", "Suspicious Fisherman") + .withDataFileDigestAlgorithm(DigestAlgorithm.SHA384) + .withSignatureDigestAlgorithm(DigestAlgorithm.SHA224) + .withSignatureProfile(SignatureProfile.LTA) + .withSignatureToken(pkcs12SignatureToken); + + Signature signature = signatureBuilder.invokeSigning(); + + Assert.assertNotNull(signature); + assertSignatureIsValid(signature, SignatureProfile.LTA); + assertThat(signature.getCity(), equalTo("Tallinn")); + assertThat(signature.getStateOrProvince(), equalTo("Harjumaa")); + assertThat(signature.getPostalCode(), equalTo("13456")); + assertThat(signature.getCountryName(), equalTo("Estonia")); + assertThat(signature.getSignerRoles(), hasSize(2)); + assertThat(signature.getSignerRoles(), containsInRelativeOrder("Manager", "Suspicious Fisherman")); } @Test - public void signContainerWithSignatureToken() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = SignatureBuilder.aSignature(container).withCity("Tallinn"). - withStateOrProvince("Harjumaa").withPostalCode("13456").withCountry("Estonia"). - withRoles("Manager", "Suspicious Fisherman").withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).withSignatureToken(pkcs12SignatureToken).invokeSigning(); + public void signContainerWithSignatureToken() { + Container container = createNonEmptyContainerBy(ASICE); + Signature signature = SignatureBuilder + .aSignature(container) + .withCity("Tallinn") + .withStateOrProvince("Harjumaa") + .withPostalCode("13456") + .withCountry("Estonia") + .withRoles("Manager", "Suspicious Fisherman") + .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) + .withSignatureProfile(SignatureProfile.LT) + .withSignatureToken(pkcs12SignatureToken) + .invokeSigning(); container.addSignature(signature); Assert.assertTrue(signature.validateSignature().isValid()); - container.saveAsFile(this.getFileBy("bdoc")); - this.assertSignatureIsValid(signature, SignatureProfile.LT_TM); + container.saveAsFile(getFileBy("asice")); + assertSignatureIsValid(signature, SignatureProfile.LT); Assert.assertEquals("Tallinn", signature.getCity()); Assert.assertEquals("Harjumaa", signature.getStateOrProvince()); Assert.assertEquals("13456", signature.getPostalCode()); @@ -119,107 +261,80 @@ public void signContainerWithSignatureToken() throws Exception { } @Test - public void createTimeMarkSignature_shouldNotContainTimestamp() throws Exception { - Container container = this.createNonEmptyContainer(); - BDocSignature signature = (BDocSignature) SignatureBuilder.aSignature(container). - withSignatureProfile(SignatureProfile.LT_TM).withSignatureToken(pkcs12SignatureToken).invokeSigning(); - Assert.assertTrue(signature.validateSignature().isValid()); - container.addSignature(signature); - List signatureTimestamps = signature.getOrigin().getDssSignature().getSignatureTimestamps(); - Assert.assertTrue(signatureTimestamps == null || signatureTimestamps.isEmpty()); - } + public void invokeSigning_WhenSignatureTokenIsMissingForASiCE_ThrowsSignatureTokenMissingException() { + Container container = createNonEmptyContainerBy(ASICE); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - @Test(expected = SignatureTokenMissingException.class) - public void signContainerWithMissingSignatureToken_shouldThrowException() throws Exception { - Container container = this.createNonEmptyContainer(); - SignatureBuilder.aSignature(container).invokeSigning(); + assertThrows( + SignatureTokenMissingException.class, + signatureBuilder::invokeSigning + ); } @Test - public void signatureProfileShouldBeSetProperlyForBDoc() throws Exception { - Signature signature = createBDocSignatureWithProfile(SignatureProfile.B_BES); - Assert.assertEquals(SignatureProfile.B_BES, signature.getProfile()); - Assert.assertTrue(signature.getSignerRoles().isEmpty()); - } + public void invokeSigning_WhenSignatureTokenIsMissingForBDOC_ThrowsSignatureTokenMissingException() { + Container container = createNonEmptyContainerBy(BDOC); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - @Test - public void signatureProfileShouldBeSetProperlyForBDocTS() throws Exception { - Signature signature = createBDocSignatureWithProfile(SignatureProfile.LT); - Assert.assertEquals(SignatureProfile.LT, signature.getProfile()); + assertThrows( + SignatureTokenMissingException.class, + signatureBuilder::invokeSigning + ); } @Test - public void signatureProfileShouldBeSetProperlyForBDocTM() throws Exception { - Signature signature = createBDocSignatureWithProfile(SignatureProfile.LT_TM); - Assert.assertEquals(SignatureProfile.LT_TM, signature.getProfile()); - } + public void invokeSigning_WhenSignatureTokenIsMissingForASiCS_ThrowsSignatureTokenMissingException() { + Container container = createNonEmptyContainerBy(ASICS); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - @Test - public void signatureProfileShouldBeSetProperlyForBEpes() throws Exception { - Signature signature = createBDocSignatureWithProfile(SignatureProfile.B_EPES); - Assert.assertEquals(SignatureProfile.B_EPES, signature.getProfile()); - Assert.assertNull(signature.getTrustedSigningTime()); - Assert.assertNull(signature.getOCSPCertificate()); - Assert.assertNull(signature.getOCSPResponseCreationTime()); - Assert.assertNull(signature.getTimeStampTokenCertificate()); - Assert.assertNull(signature.getTimeStampCreationTime()); - AsicESignature bDocSignature = (AsicESignature) signature; - SignaturePolicy policyId = bDocSignature.getOrigin().getDssSignature().getSignaturePolicy(); - Assert.assertEquals("1.3.6.1.4.1.10015.1000.3.2.1", policyId.getIdentifier()); + assertThrows( + SignatureTokenMissingException.class, + signatureBuilder::invokeSigning + ); } @Test - public void signWithEccCertificate() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = SignatureBuilder.aSignature(container). - withSignatureToken(new PKCS12SignatureToken("src/test/resources/testFiles/p12/MadDogOY.p12", "test".toCharArray())). - withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).invokeSigning(); + public void signWithEccCertificate() { + Container container = createNonEmptyContainer(); + Signature signature = SignatureBuilder.aSignature(container).withSignatureToken(pkcs12EccSignatureToken) + .withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).invokeSigning(); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("ecdsa")); Assert.assertEquals(SignatureProfile.LT, signature.getProfile()); container.addSignature(signature); Assert.assertTrue(container.validate().isValid()); } @Test - public void signWith2EccCertificate() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = SignatureBuilder.aSignature(container).withSignatureToken(pkcs12EccSignatureToken). - withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).invokeSigning(); - Assert.assertTrue(signature.validateSignature().isValid()); - container.addSignature(signature); - signature = SignatureBuilder.aSignature(container). - withSignatureToken(new PKCS12SignatureToken("src/test/resources/testFiles/p12/MadDogOY.p12", "test".toCharArray())). - withEncryptionAlgorithm(EncryptionAlgorithm.RSA).withSignatureProfile(SignatureProfile.LT).invokeSigning(); + public void signWith2EccCertificate() { + Container container = createNonEmptyContainer(); + Signature signature = SignatureBuilder.aSignature(container).withSignatureToken(pkcs12EccSignatureToken) + .withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) + .withSignatureProfile(SignatureProfile.LT).invokeSigning(); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("ecdsa")); container.addSignature(signature); - Assert.assertTrue(container.validate().isValid()); - } - - @Test - public void signTMWithEccCertificate() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = SignatureBuilder.aSignature(container). - withSignatureToken(new PKCS12SignatureToken("src/test/resources/testFiles/p12/MadDogOY.p12", "test".toCharArray())). - withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).invokeSigning(); - Assert.assertNotNull(signature); + signature = SignatureBuilder.aSignature(container) + .withSignatureToken(pkcs12Esteid2018SignatureToken) + .withEncryptionAlgorithm(EncryptionAlgorithm.RSA).withSignatureProfile(SignatureProfile.LT).invokeSigning(); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("ecdsa")); container.addSignature(signature); Assert.assertTrue(container.validate().isValid()); } @Test - public void signWithEccCertificate_determiningEncryptionAlgorithmAutomatically() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = this.createSignatureBy(container, new PKCS12SignatureToken("src/test/resources/testFiles/p12/MadDogOY.p12", "test".toCharArray())); + public void signWithEccCertificate_determiningEncryptionAlgorithmAutomatically() { + Container container = createNonEmptyContainer(); + Signature signature = createSignatureBy(container, pkcs12EccSignatureToken); Assert.assertNotNull(signature); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("ecdsa")); } @Test public void signWithDeterminedSignatureDigestAlgorithm() throws Exception { - Container container = this.createNonEmptyContainer(); + Container container = createNonEmptyContainer(); DigestAlgorithm digestAlgorithm = TokenAlgorithmSupport.determineSignatureDigestAlgorithm(pkcs12SignatureToken.getCertificate()); DataToSign dataToSign = SignatureBuilder.aSignature(container). withSignatureDigestAlgorithm(digestAlgorithm).withSigningCertificate(pkcs12SignatureToken.getCertificate()). @@ -231,36 +346,44 @@ public void signWithDeterminedSignatureDigestAlgorithm() throws Exception { Assert.assertTrue(container.validate().isValid()); } - @Test(expected = InvalidSignatureException.class) - public void openSignatureFromNull_shouldThrowException() throws Exception { - SignatureBuilder.aSignature(this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"))). - openAdESSignature(null); + @Test + public void openSignatureFromNull_shouldThrowException() { + SignatureBuilder signatureBuilder = SignatureBuilder + .aSignature(createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"))); + + InvalidSignatureException caughtException = assertThrows( + InvalidSignatureException.class, + () -> signatureBuilder.openAdESSignature(null) + ); + + assertThat(caughtException.getMessage(), equalTo("Invalid signature document")); } @Test public void openSignatureFromExistingSignatureDocument() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); - Signature signature = this.openSignatureFromExistingSignatureDocument(container); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); + Signature signature = openSignatureFromExistingSignatureDocument(container); Assert.assertTrue(signature.validateSignature().isValid()); } - @Test(expected = NotSupportedException.class) - public void SignatureBuilderWithDDoc_throwsException() throws Exception { - Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); - SignatureBuilder.aSignature(container).buildDataToSign(); - } - - @Test(expected = InvalidSignatureException.class) + @Test public void openSignatureFromInvalidSignatureDocument() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); byte[] signatureBytes = FileUtils.readFileToByteArray(new File("src/test/resources/testFiles/helper-files/test.txt")); - SignatureBuilder.aSignature(container).openAdESSignature(signatureBytes); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + InvalidSignatureException caughtException = assertThrows( + InvalidSignatureException.class, + () -> signatureBuilder.openAdESSignature(signatureBytes) + ); + + assertThat(caughtException.getMessage(), equalTo("Invalid signature document")); } @Test public void openSignature_withDataFilesMismatch_shouldBeInvalid() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/word_file.docx")); - Signature signature = this.openAdESSignature(container); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/word_file.docx")); + Signature signature = openAdESSignature(container); ValidationResult result = signature.validateSignature(); Assert.assertFalse(result.isValid()); TestAssert.assertContainsErrors(result.getErrors(), @@ -270,7 +393,7 @@ public void openSignature_withDataFilesMismatch_shouldBeInvalid() throws Excepti @Test public void openXadesSignature_withoutXmlPreamble_shouldNotThrowException() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); byte[] signatureBytes = FileUtils.readFileToByteArray(new File("src/test/resources/testFiles/xades/bdoc-tm-jdigidoc-mobile-id.xml")); SignatureBuilder.aSignature(container).openAdESSignature(signatureBytes); } @@ -278,9 +401,9 @@ public void openXadesSignature_withoutXmlPreamble_shouldNotThrowException() thro @Test public void openXadesSignature_andSavingContainer_shouldNotChangeSignature() throws Exception { Container container = TestDataBuilderUtil.createContainerWithFile("src/test/resources/testFiles/helper-files/word_file.docx"); - Signature signature = this.openAdESSignature(container); + Signature signature = openAdESSignature(container); container.addSignature(signature); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); byte[] originalSignatureBytes = FileUtils.readFileToByteArray(new File("src/test/resources/testFiles/xades/valid-bdoc-tm.xml")); @@ -288,11 +411,17 @@ public void openXadesSignature_andSavingContainer_shouldNotChangeSignature() thr Assert.assertArrayEquals(originalSignatureBytes, signatureBytes); } - @Test(expected = NotSupportedException.class) + @Test public void signUnknownContainerFormat_shouldThrowException() throws Exception { ContainerBuilder.setContainerImplementation("TEST-FORMAT", CustomContainer.class); - Container container = TestDataBuilderUtil.createContainerWithFile(this.testFolder, "TEST-FORMAT"); - TestDataBuilderUtil.buildDataToSign(container); + Container container = TestDataBuilderUtil.createContainerWithFile(testFolder, "TEST-FORMAT"); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureBuilder.aSignature(container) + ); + + assertThat(caughtException.getMessage(), containsString("Unknown container type: TEST-FORMAT")); } @Test @@ -308,25 +437,8 @@ public void signCustomContainer() throws Exception { } @Test - public void signAsiceContainerWithExtRsaTm() throws Exception { - Container container = this.createNonEmptyContainer(); - DataToSign dataToSign = SignatureBuilder.aSignature(container).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).withSigningCertificate(pkcs12SignatureToken.getCertificate()). - buildDataToSign(); - Assert.assertNotNull(dataToSign); - // This call mocks the using of external signing functionality with hashcode - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); - Assert.assertNotNull(signature); - Assert.assertTrue(signature.validateSignature().isValid()); - container.addSignature(signature); - Assert.assertTrue(container.validate().isValid()); - container.saveAsFile(this.getFileBy("bdoc")); - } - - @Test - public void signAsiceContainerWithExtRsaLt() throws Exception { - Container container = this.createNonEmptyContainer(); + public void signAsiceContainerWithExtRsaLt() { + Container container = createNonEmptyContainerBy(ASICE); DataToSign dataToSign = SignatureBuilder.aSignature(container).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). withSignatureProfile(SignatureProfile.LT).withSigningCertificate(pkcs12SignatureToken.getCertificate()). buildDataToSign(); @@ -336,73 +448,41 @@ public void signAsiceContainerWithExtRsaLt() throws Exception { Signature signature = dataToSign.finalize(signatureValue); Assert.assertNotNull(signature); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("rsa")); container.addSignature(signature); Assert.assertTrue(container.validate().isValid()); - container.saveAsFile(this.getFileBy("asice")); - } - - @Test - public void signAsiceContainerWithExtEccTm() throws Exception { - Security.addProvider(new BouncyCastleProvider()); - String TEST_ECC_PKI_CONTAINER = "src/test/resources/testFiles/p12/MadDogOY.p12"; - String TEST_ECC_PKI_CONTAINER_PASSWORD = "test"; - PKCS12SignatureToken token = new PKCS12SignatureToken(TEST_ECC_PKI_CONTAINER, TEST_ECC_PKI_CONTAINER_PASSWORD, - "test of esteid-sk 2011: mad dog oy"); - Assert.assertEquals("test of esteid-sk 2011: mad dog oy", token.getAlias()); - Container container = this.createNonEmptyContainer(); - DataToSign dataToSign = SignatureBuilder.aSignature(container).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT_TM).withSigningCertificate(token.getCertificate()). - buildDataToSign(); - Assert.assertNotNull(dataToSign); - // This call mocks the using of external signing functionality with hashcode - byte[] signatureValue = new byte[1]; - int counter = 5; - do { - signatureValue = token.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - counter--; - } while (signatureValue.length == 72 && counter > 0); // Somehow the signature with length 72 is not correct - Signature signature = dataToSign.finalize(signatureValue); - Assert.assertNotNull(signature); - Assert.assertTrue(signature.validateSignature().isValid()); - container.addSignature(signature); - Assert.assertTrue(container.validate().isValid()); - container.saveAsFile(this.getFileBy("asice")); + container.saveAsFile(getFileBy("asice")); } @Test - public void signAsiceContainerWithExtEccLt() throws Exception { - Security.addProvider(new BouncyCastleProvider()); - String TEST_ECC_PKI_CONTAINER = "src/test/resources/testFiles/p12/MadDogOY.p12"; - String TEST_ECC_PKI_CONTAINER_PASSWORD = "test"; - PKCS12SignatureToken token = new PKCS12SignatureToken(TEST_ECC_PKI_CONTAINER, TEST_ECC_PKI_CONTAINER_PASSWORD, - "test of esteid-sk 2011: mad dog oy"); - Assert.assertEquals("test of esteid-sk 2011: mad dog oy", token.getAlias()); - Container container = this.createNonEmptyContainer(); + public void signAsiceContainerWithExtEccLt() { + Container container = createNonEmptyContainerBy(ASICE); DataToSign dataToSign = SignatureBuilder.aSignature(container).withSignatureDigestAlgorithm(DigestAlgorithm.SHA256). - withSignatureProfile(SignatureProfile.LT).withSigningCertificate(token.getCertificate()). + withSignatureProfile(SignatureProfile.LT).withSigningCertificate(pkcs12EccSignatureToken.getCertificate()). withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).buildDataToSign(); Assert.assertNotNull(dataToSign); // This call mocks the using of external signing functionality with hashcode byte[] signatureValue = new byte[1]; int counter = 5; do { - signatureValue = token.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); + signatureValue = pkcs12EccSignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); counter--; } while (signatureValue.length == 72 && counter > 0); // Somehow the signature with length 72 is not correct Signature signature = dataToSign.finalize(signatureValue); Assert.assertNotNull(signature); Assert.assertTrue(signature.validateSignature().isValid()); + assertThat(signature.getSignatureMethod(), containsString("ecdsa")); container.addSignature(signature); Assert.assertTrue(container.validate().isValid()); - container.saveAsFile(this.getFileBy("asice")); + container.saveAsFile(getFileBy("asice")); } @Test public void invokeSigningForCustomContainer() throws Exception { ContainerBuilder.setContainerImplementation("TEST-FORMAT", CustomContainer.class); SignatureBuilder.setSignatureBuilderForContainerType("TEST-FORMAT", MockSignatureBuilder.class); - Container container = TestDataBuilderUtil.createContainerWithFile(this.testFolder, "TEST-FORMAT"); + Container container = TestDataBuilderUtil.createContainerWithFile(testFolder, "TEST-FORMAT"); Signature signature = SignatureBuilder.aSignature(container).withSignatureToken(pkcs12SignatureToken). invokeSigning(); Assert.assertNotNull(signature); @@ -421,75 +501,38 @@ public void invokingSigningBBesSignatureForAsicEContainer() { assertBBesSignature(signature); } - @Test(expected = IllegalSignatureProfileException.class) - public void invokingSigningTMSignatureForAsicEContainer_throwsException() { - Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); - assertAsicEContainer(container); - - SignatureBuilder.aSignature(container) - .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) - .withSignatureProfile(SignatureProfile.LT_TM) - .withSignatureToken(pkcs12SignatureToken) - .invokeSigning(); - } - - @Test(expected = IllegalSignatureProfileException.class) - public void invokingSigningBEpesSignatureForAsicEContainer_throwsException() { - Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); - assertAsicEContainer(container); - - SignatureBuilder.aSignature(container) - .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) - .withSignatureProfile(SignatureProfile.B_EPES) - .withSignatureToken(pkcs12SignatureToken) - .invokeSigning(); - } - @Test public void invokeSigning_whenOverridingBDocContainerFormat() { CustomContainer.type = "BDOC"; ContainerBuilder.setContainerImplementation("BDOC", CustomContainer.class); SignatureBuilder.setSignatureBuilderForContainerType("BDOC", MockSignatureBuilder.class); - Container container = this.createNonEmptyContainer(); - Signature signature = this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainer(); + Signature signature = createSignatureBy(container, pkcs12SignatureToken); Assert.assertNotNull(signature); CustomContainer.resetType(); } @Test - public void buildingBEpesSignatureResultsWithBDocSignature() { - Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) - .withSignatureProfile(SignatureProfile.B_EPES) - .buildDataToSign(); - - Signature signature = dataToSign.finalize(pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign())); - assertBEpesSignature(signature); - } - - @Test - public void bDocContainerWithTMSignature_signWithTimemarkSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_SIG); + public void bDocContainerWithTMSignature_signWithBesSignature_shouldSucceed() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); assertBDocContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); - Signature signature = signContainerWithSignature(container, SignatureProfile.LT_TM); - assertTimemarkSignature(signature); - Assert.assertTrue(signature.validateSignature().isValid()); + Signature signature = signContainerWithSignature(container, SignatureProfile.B_BES); + assertBBesSignature(signature); + Assert.assertFalse(signature.validateSignature().isValid()); container.addSignature(signature); assertBDocContainer(container); Assert.assertSame(2, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); - assertTimemarkSignature(container.getSignatures().get(1)); + assertBBesSignature(container.getSignatures().get(1)); } @Test public void bDocContainerWithTMSignature_signWithTimestampSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_SIG); + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); assertBDocContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); @@ -506,52 +549,152 @@ public void bDocContainerWithTMSignature_signWithTimestampSignature_shouldSuccee } @Test - public void bDocContainerWithTMSignature_signWithBEpesSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_SIG); + public void bDocContainerWithTMSignature_signWithArchiveTimestampSignature_shouldSucceed() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); assertBDocContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); - Signature signature = signContainerWithSignature(container, SignatureProfile.B_EPES); - assertBEpesSignature(signature); + Signature signature = signContainerWithSignature(container, SignatureProfile.LTA); + assertArchiveTimestampSignature(signature); + Assert.assertTrue(signature.validateSignature().isValid()); container.addSignature(signature); assertBDocContainer(container); Assert.assertSame(2, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); - assertBEpesSignature(container.getSignatures().get(1)); + assertArchiveTimestampSignature(container.getSignatures().get(1)); } @Test - public void bDocContainerWithTMAndTSSignature_signWithTimestampSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_AND_TS_SIG); + public void bDocContainerWithTMSignature_withSignatureProfileB_EPES_shouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); + } + + @Test + public void bDocContainerWithTMSignature_withSignatureProfileLT_TM_shouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); + } + + @Test + public void bDocContainerWithTMSignature_withOwnSignaturePolicy_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMSignature_withOwnSignaturePolicyWithB_BES_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.B_BES); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMSignature_withOwnSignaturePolicyWithLT_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMSignature_withOwnSignaturePolicyWithLTA_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_SIG); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LTA); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMAndTSSignature_signWithBesSignature_shouldSucceed() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); assertBDocContainer(container); Assert.assertSame(2, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); assertTimestampSignature(container.getSignatures().get(1)); - Signature signature = signContainerWithSignature(container, SignatureProfile.LT); - assertTimestampSignature(signature); - Assert.assertTrue(signature.validateSignature().isValid()); + Signature signature = signContainerWithSignature(container, SignatureProfile.B_BES); + assertBBesSignature(signature); + Assert.assertFalse(signature.validateSignature().isValid()); container.addSignature(signature); assertBDocContainer(container); Assert.assertSame(3, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); assertTimestampSignature(container.getSignatures().get(1)); - assertTimestampSignature(container.getSignatures().get(2)); + assertBBesSignature(container.getSignatures().get(2)); } @Test - public void bDocContainerWithTMAndTSSignature_signWithTimemarkSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_AND_TS_SIG); + public void bDocContainerWithTMAndTSSignature_signWithTimestampSignature_shouldSucceed() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); assertBDocContainer(container); Assert.assertSame(2, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); assertTimestampSignature(container.getSignatures().get(1)); - Signature signature = signContainerWithSignature(container, SignatureProfile.LT_TM); - assertTimemarkSignature(signature); + Signature signature = signContainerWithSignature(container, SignatureProfile.LT); + assertTimestampSignature(signature); Assert.assertTrue(signature.validateSignature().isValid()); container.addSignature(signature); @@ -559,12 +702,12 @@ public void bDocContainerWithTMAndTSSignature_signWithTimemarkSignature_shouldSu Assert.assertSame(3, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); assertTimestampSignature(container.getSignatures().get(1)); - assertTimemarkSignature(container.getSignatures().get(2)); + assertTimestampSignature(container.getSignatures().get(2)); } @Test public void bDocContainerWithTMAndTSSignature_signWithArchiveTimestampSignature_shouldSucceed() { - Container container = buildContainer(BDOC_WITH_TM_AND_TS_SIG); + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); assertBDocContainer(container); Assert.assertSame(2, container.getSignatures().size()); assertTimemarkSignature(container.getSignatures().get(0)); @@ -583,34 +726,155 @@ public void bDocContainerWithTMAndTSSignature_signWithArchiveTimestampSignature_ } @Test - public void bDocContainerWithoutSignatures_signWithoutAssignedProfile_defaultPofileIsUsed_shouldSucceedWithTimestampSignature() { - Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + public void bDocContainerWithTMAndTSSignature_withSignatureProfileB_EPES_shouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); assertBDocContainer(container); - Assert.assertTrue(container.getSignatures().isEmpty()); - - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) - .buildDataToSign(); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - Signature signature = dataToSign.finalize(pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign())); - Assert.assertSame(Constant.Default.SIGNATURE_PROFILE, signature.getProfile()); - assertTimestampSignature(signature); - assertValidSignature(signature); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); - container.addSignature(signature); - assertBDocContainer(container); - Assert.assertSame(1, container.getSignatures().size()); - assertTimestampSignature(container.getSignatures().get(0)); + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); } @Test - public void bDocContainerWithoutSignatures_signWithTimestampSignature_shouldSucceed() { - Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + public void bDocContainerWithTMAndTSSignature_withSignatureProfileLT_TM_shouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); assertBDocContainer(container); - Assert.assertTrue(container.getSignatures().isEmpty()); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - Signature signature = signContainerWithSignature(container, SignatureProfile.LT); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); + } + + @Test + public void bDocContainerWithTMAndTSSignature_withOwnSignaturePolicy_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); + assertBDocContainer(container); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMAndTSSignature_withOwnSignaturePolicyWithB_BES_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); + assertBDocContainer(container); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.B_BES); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMAndTSSignature_withOwnSignaturePolicyWithLT_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); + assertBDocContainer(container); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithTMAndTSSignature_withOwnSignaturePolicyWithLTA_ShouldFail() { + Container container = buildContainer(BDOC, BDOC_WITH_TM_AND_TS_SIG); + assertBDocContainer(container); + Assert.assertSame(2, container.getSignatures().size()); + assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(1)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LTA); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithoutSignatures_signWithoutAssignedProfile_defaultProfileIsUsed_shouldSucceedWithTimestampSignature() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + + DataToSign dataToSign = SignatureBuilder.aSignature(container) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()) + .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256) + .buildDataToSign(); + + Signature signature = dataToSign.finalize(pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign())); + Assert.assertSame(Constant.Default.SIGNATURE_PROFILE, signature.getProfile()); + assertTimestampSignature(signature); + assertValidSignature(signature); + + container.addSignature(signature); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + } + + @Test + public void bDocContainerWithoutSignatures_signWithBesSignature_shouldSucceed() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + + Signature signature = signContainerWithSignature(container, SignatureProfile.B_BES); + assertBBesSignature(signature); + Assert.assertFalse(signature.validateSignature().isValid()); + + container.addSignature(signature); + assertBDocContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertBBesSignature(container.getSignatures().get(0)); + } + + @Test + public void bDocContainerWithoutSignatures_signWithTimestampSignature_shouldSucceed() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + + Signature signature = signContainerWithSignature(container, SignatureProfile.LT); assertTimestampSignature(signature); Assert.assertTrue(signature.validateSignature().isValid()); @@ -621,19 +885,112 @@ public void bDocContainerWithoutSignatures_signWithTimestampSignature_shouldSucc } @Test - public void bDocContainerWithoutSignatures_signWithTimemarkSignature_shouldSucceed() { + public void bDocContainerWithoutSignatures_signWithArchiveTimestampSignature_shouldSucceed() { Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); assertBDocContainer(container); Assert.assertTrue(container.getSignatures().isEmpty()); - Signature signature = signContainerWithSignature(container, SignatureProfile.LT_TM); - assertTimemarkSignature(signature); + Signature signature = signContainerWithSignature(container, SignatureProfile.LTA); + assertArchiveTimestampSignature(signature); Assert.assertTrue(signature.validateSignature().isValid()); container.addSignature(signature); assertBDocContainer(container); Assert.assertSame(1, container.getSignatures().size()); - assertTimemarkSignature(container.getSignatures().get(0)); + assertArchiveTimestampSignature(container.getSignatures().get(0)); + } + + @Test + public void bDocContainerWithoutSignatures_withSignatureProfileB_EPES_shouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); + } + + @Test + public void bDocContainerWithoutSignatures_withSignatureProfileLT_TM_shouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); + } + + @Test + public void bDocContainerWithoutSignatures_withOwnSignaturePolicy_ShouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithoutSignatures_withOwnSignaturePolicyWithB_BES_ShouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.B_BES); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithoutSignatures_withOwnSignaturePolicyWithLT_ShouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void bDocContainerWithoutSignatures_withOwnSignaturePolicyWithLTA_ShouldFail() { + Container container = buildContainer(BDOC, ASIC_WITH_NO_SIG); + assertBDocContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LTA); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } @Test @@ -689,8 +1046,8 @@ public void signWith384EcKey_withoutAssigningSignatureDigestAlgo_sha384Signature } @Test - public void signWithDifferentDataFileAndSignatureDigestAlgorithm() throws Exception { - Container container = this.createNonEmptyContainer(); + public void signWithDifferentDataFileAndSignatureDigestAlgorithm() { + Container container = createNonEmptyContainer(); DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSignatureDigestAlgorithm(DigestAlgorithm.SHA384) .withDataFileDigestAlgorithm(DigestAlgorithm.SHA512) @@ -704,6 +1061,22 @@ public void signWithDifferentDataFileAndSignatureDigestAlgorithm() throws Except Assert.assertTrue(container.validate().isValid()); } + @Test + public void asiceContainerWithoutSignatures_signWithBesSignature_shouldSucceed() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + + Signature signature = signContainerWithSignature(container, SignatureProfile.B_BES); + assertBBesSignature(signature); + Assert.assertFalse(signature.validateSignature().isValid()); + + container.addSignature(signature); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertBBesSignature(container.getSignatures().get(0)); + } + @Test public void asiceContainerWithoutSignatures_signWithTimestampSignature_shouldSucceed() { Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); @@ -720,19 +1093,136 @@ public void asiceContainerWithoutSignatures_signWithTimestampSignature_shouldSuc assertTimestampSignature(container.getSignatures().get(0)); } - @Test(expected = IllegalSignatureProfileException.class) - public void asiceContainerWithoutSignatures_signWithTimemarkSignature_shouldFail() { + @Test + public void asiceContainerWithoutSignatures_signWithArchiveTimestampSignature_shouldSucceed() { Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + + Signature signature = signContainerWithSignature(container, SignatureProfile.LTA); + assertArchiveTimestampSignature(signature); + Assert.assertTrue(signature.validateSignature().isValid()); + + container.addSignature(signature); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertArchiveTimestampSignature(container.getSignatures().get(0)); + } + @Test + public void asiceContainerWithoutSignatures_withSignatureProfileB_EPES_shouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); - buildDataToSign(container, SignatureProfile.LT_TM); + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); + } + + @Test + public void asiceContainerWithoutSignatures_withSignatureProfileLT_TM_shouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); + } + + @Test + public void asiceContainerWithoutSignatures_withOwnSignaturePolicy_ShouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void asiceContainerWithoutSignatures_withOwnSignaturePolicyWithB_BES_ShouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.B_BES); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void asiceContainerWithoutSignatures_withOwnSignaturePolicyWithLT_ShouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void asiceContainerWithoutSignatures_withOwnSignaturePolicyWithLTA_ShouldFail() { + Container container = buildContainer(ASICE, ASIC_WITH_NO_SIG); + assertAsicEContainer(container); + Assert.assertTrue(container.getSignatures().isEmpty()); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LTA); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void asicEContainerWithTSSignature_signWithBesSignature_shouldSucceed() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + + Signature signature = signContainerWithSignature(container, SignatureProfile.B_BES); + assertBBesSignature(signature); + Assert.assertFalse(signature.validateSignature().isValid()); + + container.addSignature(signature); + assertAsicEContainer(container); + Assert.assertSame(2, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + assertBBesSignature(container.getSignatures().get(1)); } @Test public void asicEContainerWithTSSignature_signWithTimestampSignature_shouldSucceed() { - Container container = buildContainer(ASICE_WITH_TS_SIG); + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); assertAsicEContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimestampSignature(container.getSignatures().get(0)); @@ -750,7 +1240,7 @@ public void asicEContainerWithTSSignature_signWithTimestampSignature_shouldSucce @Test public void asicEContainerWithTSSignature_signWithArchiveTimestampSignature_shouldSucceed() { - Container container = buildContainer(ASICE_WITH_TS_SIG); + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); assertAsicEContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimestampSignature(container.getSignatures().get(0)); @@ -766,81 +1256,116 @@ public void asicEContainerWithTSSignature_signWithArchiveTimestampSignature_shou assertArchiveTimestampSignature(container.getSignatures().get(1)); } - @Test(expected = IllegalSignatureProfileException.class) - public void asicEContainerWithTSSignature_signWithTimemarkSignature_shouldFail() { - Container container = buildContainer(ASICE_WITH_TS_SIG); + @Test + public void asicEContainerWithTSSignature_withSignatureProfileB_EPES_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); assertAsicEContainer(container); Assert.assertSame(1, container.getSignatures().size()); assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.B_EPES) + ); - buildDataToSign(container, SignatureProfile.LT_TM); + assertThat(caughtException.getMessage(), containsString("Can't create B_EPES signatures")); } @Test - public void customSignaturePolicyAllowedForLT_TMSignatureProfile_resultsWithLTProfileBDocSignature() { - Container container = ContainerBuilder.aContainer(BDOC).build(); - container.addDataFile(new ByteArrayInputStream("something".getBytes()), "name", "text/plain"); - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); + public void asicEContainerWithTSSignature_withSignatureProfileLT_TM_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withSignatureProfile(SignatureProfile.LT_TM) + ); - Assert.assertNotNull(signature); - Assert.assertTrue(signature instanceof BDocSignature); - Assert.assertEquals(SignatureProfile.LT, signature.getProfile()); + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); } @Test - public void customSignaturePolicyWhenSignatureProfileNotSet_resultsWithTimestampSignature() { - Container container = ContainerBuilder.aContainer(BDOC).build(); - container.addDataFile(new ByteArrayInputStream("something".getBytes()), "name", "text/plain"); - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); + public void asicEContainerWithTSSignature_withOwnSignaturePolicy_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); - assertTimestampSignature(signature); + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } - @Test(expected = NotSupportedException.class) - public void signatureProfileLTNotAllowedForCustomSignaturePolicy() { - Container container = ContainerBuilder.aContainer(BDOC).build(); - container.addDataFile(new ByteArrayInputStream("something".getBytes()), "name", "text/plain"); - SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withOwnSignaturePolicy(validCustomPolicy()) - .withSignatureProfile(SignatureProfile.LT) - .buildDataToSign(); + @Test + public void asicEContainerWithTSSignature_withOwnSignaturePolicyWithB_BES_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.B_BES); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } - @Test(expected = NotSupportedException.class) - public void customSignaturePolicyNotAllowedForLTSignatureProfile() { - Container container = ContainerBuilder.aContainer(ASICE).build(); - container.addDataFile(new ByteArrayInputStream("something".getBytes()), "name", "text/plain"); - SignatureBuilder.aSignature(container) - .withSignatureProfile(SignatureProfile.LT) - .withOwnSignaturePolicy(validCustomPolicy()) - .buildDataToSign(); + @Test + public void asicEContainerWithTSSignature_withOwnSignaturePolicyWithLT_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); + } + + @Test + public void asicEContainerWithTSSignature_withOwnSignaturePolicyWithLTA_ShouldFail() { + Container container = buildContainer(ASICE, ASICE_WITH_TS_SIG); + assertAsicEContainer(container); + Assert.assertSame(1, container.getSignatures().size()); + assertTimestampSignature(container.getSignatures().get(0)); + SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container) + .withSignatureProfile(SignatureProfile.LTA); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> signatureBuilder.withOwnSignaturePolicy(validCustomPolicy()) + ); + + assertThat(caughtException.getMessage(), containsString("Can't define signature policy")); } @Test public void claimedSigningTimeInitializedDuringDataToSignBuilding() { - Container container = ContainerBuilder.aContainer(BDOC).build(); + Container container = ContainerBuilder.aContainer(ASICE).build(); container.addDataFile(new ByteArrayInputStream("something".getBytes()), "name", "text/plain"); - long claimedSigningTimeLowerBound = new Date().getTime() / 1000 * 1000; - DataToSign dataToSign = buildDataToSign(container, SignatureProfile.LT_TM); - long claimedSigningTimeUpperBound = new Date().getTime() + 1000; + Instant claimedSigningTimeLowerBound = Instant.now().truncatedTo(ChronoUnit.SECONDS); + DataToSign dataToSign = buildDataToSign(container, SignatureProfile.LT); + Instant claimedSigningTimeUpperBound = Instant.now(); - long claimedSigningTime = dataToSign.getSignatureParameters().getClaimedSigningDate().getTime(); - assertTrue(claimedSigningTime >= claimedSigningTimeLowerBound); - assertTrue(claimedSigningTime <= claimedSigningTimeUpperBound); + Date claimedSigningTime = dataToSign.getSignatureParameters().getClaimedSigningDate(); + assertTimeInBounds(claimedSigningTime, claimedSigningTimeLowerBound, claimedSigningTimeUpperBound, Duration.ZERO); } @Test @@ -894,7 +1419,7 @@ private DataToSign buildDataToSign(Container container, SignatureProfile signatu private Container buildContainer(Container.DocumentType documentType, String path) { try (InputStream stream = FileUtils.openInputStream(new File(path))) { - return BDocContainerBuilder + return ContainerBuilder .aContainer(documentType) .fromStream(stream) .build(); @@ -904,18 +1429,6 @@ private Container buildContainer(Container.DocumentType documentType, String pat } } - private Container buildContainer(String path) { - try (InputStream stream = FileUtils.openInputStream(new File(path))) { - return BDocContainerBuilder - .aContainer(Container.DocumentType.BDOC) - .fromStream(stream) - .build(); - } catch (IOException e) { - fail("Failed to read container from stream"); - throw new IllegalStateException(e); - } - } - /* * RESTRICTED METHODS */ @@ -926,14 +1439,8 @@ protected void after() { SignatureBuilder.removeCustomSignatureBuilders(); } - private Signature createBDocSignatureWithProfile(SignatureProfile signatureProfile) { - Container container = this.createNonEmptyContainer(); - Signature signature = this.createSignatureBy(container, signatureProfile, pkcs12SignatureToken); - return signature; - } - private Signature openSignatureFromExistingSignatureDocument(Container container) throws IOException { - Signature signature = this.openAdESSignature(container); + Signature signature = openAdESSignature(container); Assert.assertEquals("id-6a5d6671af7a9e0ab9a5e4d49d69800d", signature.getId()); return signature; } @@ -948,7 +1455,7 @@ private void assertSignatureIsValid(Signature signature, SignatureProfile expect Assert.assertEquals(expectedSignatureProfile, signature.getProfile()); Assert.assertNotNull(signature.getClaimedSigningTime()); Assert.assertNotNull(signature.getAdESSignature()); - Assert.assertTrue(signature.getAdESSignature().length > 1); + assertThat(signature.getAdESSignature().length, greaterThan(1)); Assert.assertTrue(signature.validateSignature().isValid()); } } diff --git a/digidoc4j/src/test/java/org/digidoc4j/SignatureFinalizerBuilderTest.java b/digidoc4j/src/test/java/org/digidoc4j/SignatureFinalizerBuilderTest.java index bc8c0fb70..4057f1276 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/SignatureFinalizerBuilderTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/SignatureFinalizerBuilderTest.java @@ -12,9 +12,7 @@ import org.digidoc4j.exceptions.NotSupportedException; import org.digidoc4j.impl.SignatureFinalizer; -import org.digidoc4j.impl.asic.AsicSignatureFinalizer; import org.digidoc4j.impl.asic.asice.AsicESignatureFinalizer; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureFinalizer; import org.junit.Test; import java.util.ArrayList; @@ -24,63 +22,109 @@ import static org.digidoc4j.Container.DocumentType.ASICS; import static org.digidoc4j.Container.DocumentType.BDOC; import static org.digidoc4j.Container.DocumentType.DDOC; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertThrows; public class SignatureFinalizerBuilderTest { @Test - public void bdocFinalizerFromBdocContainer() { + public void aFinalizer_WhenBDOCContainerIsProvided_ReturnsAsicESignatureFinalizer() { Container container = ContainerBuilder.aContainer(BDOC).build(); - SignatureFinalizer signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(container, new SignatureParameters()); - assertTrue(signatureFinalizer instanceof BDocSignatureFinalizer); + SignatureParameters signatureParameters = new SignatureParameters(); + + SignatureFinalizer result = SignatureFinalizerBuilder.aFinalizer(container, signatureParameters); + + assertThat(result, instanceOf(AsicESignatureFinalizer.class)); } @Test - public void asiceFinalizerFromAsiceContainer() { + public void aFinalizer_WhenASICEContainerIsProvided_ReturnsAsicESignatureFinalizer() { Container container = ContainerBuilder.aContainer(ASICE).build(); - SignatureFinalizer signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(container, new SignatureParameters()); - assertTrue(signatureFinalizer instanceof AsicESignatureFinalizer); + SignatureParameters signatureParameters = new SignatureParameters(); + + SignatureFinalizer result = SignatureFinalizerBuilder.aFinalizer(container, signatureParameters); + + assertThat(result, instanceOf(AsicESignatureFinalizer.class)); } @Test - public void asicFinalizerFromAsicsContainer() { + public void aFinalizer_WhenASICSContainerIsProvided_ThrowsNotSupportedException() { Container container = ContainerBuilder.aContainer(ASICS).build(); - SignatureFinalizer signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(container, new SignatureParameters()); - assertTrue(signatureFinalizer instanceof AsicSignatureFinalizer); - } + SignatureParameters signatureParameters = new SignatureParameters(); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureFinalizerBuilder.aFinalizer(container, signatureParameters) + ); - @Test(expected = NotSupportedException.class) - public void finalizerFromContainer_notSupportedContainerType() { - Container container = ContainerBuilder.aContainer(DDOC).build(); - SignatureFinalizerBuilder.aFinalizer(container, new SignatureParameters()); + assertThat(caughtException.getMessage(), containsString("Creation of ASiC-S signatures is not supported")); } @Test - public void bdocFinalizerFromDataFiles() { - SignatureFinalizer signatureFinalizer = buildSignatureFinalizerFromDataFiles(BDOC); - assertTrue(signatureFinalizer instanceof BDocSignatureFinalizer); + public void aFinalizer_WhenDDOCContainerIsProvided_ThrowsNotSupportedException() { + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); + SignatureParameters signatureParameters = new SignatureParameters(); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureFinalizerBuilder.aFinalizer(container, signatureParameters) + ); + + assertThat(caughtException.getMessage(), containsString("Creation of DDOC signatures is not supported")); } @Test - public void asiceFinalizerFromDataFiles() { - SignatureFinalizer signatureFinalizer = buildSignatureFinalizerFromDataFiles(ASICE); - assertTrue(signatureFinalizer instanceof AsicESignatureFinalizer); + public void aFinalizer_WhenDataFilesAreProvidedAndContainerTypeIsBDOC_ReturnsAsicESignatureFinalizer() { + List dataFiles = new ArrayList<>(); + SignatureParameters signatureParameters = new SignatureParameters(); + Configuration configuration = Configuration.getInstance(); + + SignatureFinalizer result = SignatureFinalizerBuilder + .aFinalizer(dataFiles, signatureParameters, configuration, BDOC); + + assertThat(result, instanceOf(AsicESignatureFinalizer.class)); } @Test - public void asicsFinalizerFromDataFiles() { - SignatureFinalizer signatureFinalizer = buildSignatureFinalizerFromDataFiles(ASICS); - assertTrue(signatureFinalizer instanceof AsicSignatureFinalizer); + public void aFinalizer_WhenDataFilesAreProvidedAndContainerTypeIsASICE_ReturnsAsicESignatureFinalizer() { + List dataFiles = new ArrayList<>(); + SignatureParameters signatureParameters = new SignatureParameters(); + Configuration configuration = Configuration.getInstance(); + + SignatureFinalizer result = SignatureFinalizerBuilder + .aFinalizer(dataFiles, signatureParameters, configuration, ASICE); + + assertThat(result, instanceOf(AsicESignatureFinalizer.class)); } - @Test(expected = NotSupportedException.class) - public void finalizerFromDataFiles_notSupportedContainerType() { - SignatureFinalizer signatureFinalizer = buildSignatureFinalizerFromDataFiles(DDOC); - assertTrue(signatureFinalizer instanceof BDocSignatureFinalizer); + @Test + public void aFinalizer_WhenDataFilesAreProvidedAndContainerTypeIsASICS_ThrowsNotSupportedException() { + List dataFiles = new ArrayList<>(); + SignatureParameters signatureParameters = new SignatureParameters(); + Configuration configuration = Configuration.getInstance(); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureFinalizerBuilder.aFinalizer(dataFiles, signatureParameters, configuration, ASICS) + ); + + assertThat(caughtException.getMessage(), containsString("Creation of ASiC-S signatures is not supported")); } - private SignatureFinalizer buildSignatureFinalizerFromDataFiles(Container.DocumentType documentType) { + @Test + public void aFinalizer_WhenDataFilesAreProvidedAndContainerTypeIsDDOC_ReturnsAsicESignatureFinalizer() { List dataFiles = new ArrayList<>(); - return SignatureFinalizerBuilder.aFinalizer(dataFiles, new SignatureParameters(), new Configuration(), documentType); + SignatureParameters signatureParameters = new SignatureParameters(); + Configuration configuration = Configuration.getInstance(); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> SignatureFinalizerBuilder.aFinalizer(dataFiles, signatureParameters, configuration, DDOC) + ); + + assertThat(caughtException.getMessage(), containsString("Creation of DDOC signatures is not supported")); } + } diff --git a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java index f940c583d..3b3cde689 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java @@ -47,8 +47,8 @@ public class SignatureTest extends AbstractTest { @Test public void findOcspCertificateByHashkey() { - Container container = this.openContainerByConfiguration( - Paths.get("src/test/resources/testFiles/valid-containers/OCSPRigaTest.asice"), this.configuration); + Container container = openContainerByConfiguration( + Paths.get("src/test/resources/testFiles/valid-containers/OCSPRigaTest.asice"), configuration); Signature signature = container.getSignatures().get(0); X509Cert cert = signature.getOCSPCertificate(); Assert.assertNotNull(cert); @@ -75,7 +75,7 @@ public void testTimeStampCreationTimeForBDoc() throws ParseException { @Test public void testTimeStampCreationTimeForBDocWhereNotOCSP() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_BES, + Signature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_BES, pkcs12SignatureToken); Assert.assertNull(signature.getTimeStampCreationTime()); } @@ -112,7 +112,7 @@ public void testGetSigningTimeForDDOC() { @Test public void testGetSigningTimeForBDoc() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); + Signature signature = createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); Assert.assertTrue(DateUtils.isAlmostNow(signature.getClaimedSigningTime())); } @@ -160,15 +160,15 @@ public void testGetOCSPCertificateForDDoc() throws CertificateEncodingException @Test public void testGetOCSPCertificateForBDoc() throws CertificateEncodingException { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); + Signature signature = createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); byte[] encoded = signature.getOCSPCertificate().getX509Certificate().getEncoded(); Assert.assertEquals(Certificates.OCSP_CERTIFICATE_2020, Base64.encodeBase64String(encoded)); } @Test public void testGetProducedAtForDDoc() { - this.configuration = Configuration.of(Configuration.Mode.TEST); - ConfigManagerInitializer.forceInitConfigManager(this.configuration); + configuration = Configuration.of(Configuration.Mode.TEST); + ConfigManagerInitializer.forceInitConfigManager(configuration); Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); Signature signature = container.getSignatures().get(0); Assert.assertNotNull(signature.getOCSPResponseCreationTime()); @@ -184,18 +184,18 @@ public void testGetProducedAtForBDoc() throws ParseException { @Test public void testValidationForDDoc() { - this.configuration = Configuration.of(Configuration.Mode.TEST); - ConfigManagerInitializer.forceInitConfigManager(this.configuration); + configuration = Configuration.of(Configuration.Mode.TEST); + ConfigManagerInitializer.forceInitConfigManager(configuration); Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); Assert.assertEquals(0, container.validate().getErrors().size()); } @Test public void testValidationForBDocDefaultValidation() { - this.configuration = new Configuration(Configuration.Mode.TEST); - TestTSLUtil.addSkTsaCertificateToTsl(this.configuration); + configuration = new Configuration(Configuration.Mode.TEST); + TestTSLUtil.addSkTsaCertificateToTsl(configuration); Container container = ContainerOpener.open("src/test/resources/testFiles/invalid-containers/two_signatures.bdoc", - this.configuration); + configuration); Signature signature = container.getSignatures().get(0); Assert.assertEquals(0, signature.validateSignature().getErrors().size()); signature = container.getSignatures().get(1); @@ -305,8 +305,8 @@ public void testGetSignaturesWhereSignatureDoesNotHaveLastCertificate() { @Test public void getSignatureXMLForBDOC() throws Exception { - Container container = this.createNonEmptyContainer(); - Signature signature = this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainer(); + Signature signature = createSignatureBy(container, pkcs12SignatureToken); container.saveAsFile("getSignatureXMLForBDOC.bdoc"); String signatureFromContainer = Helper.extractSignature("getSignatureXMLForBDOC.bdoc", 0); Helper.deleteFile("getSignatureXMLForBDOC.bdoc"); @@ -316,12 +316,12 @@ public void getSignatureXMLForBDOC() throws Exception { @Test public void signature_withoutProductionPlace_shouldNotThrowException() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); - this.assertProductionPlaceIsNull(container.getSignatures().get(0)); + assertProductionPlaceIsNull(container.getSignatures().get(0)); } @Test public void bDocBESSignature_TrustedSigningTime_shouldReturnNull() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_BES, + Signature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_BES, pkcs12SignatureToken); Assert.assertNull(signature.getTrustedSigningTime()); } @@ -335,16 +335,18 @@ public void dDocBESSignature_TrustedSigningTime_shouldReturnNull() { @Test public void bDocTimeMarkSignature_TrustedSigningTime_shouldReturnOCSPResponseCreationTime() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LT_TM, - pkcs12SignatureToken); + configuration = Configuration.of(Configuration.Mode.TEST); + ConfigManagerInitializer.forceInitConfigManager(configuration); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"); + Signature signature = container.getSignatures().get(0); Assert.assertNotNull(signature.getTrustedSigningTime()); Assert.assertEquals(signature.getOCSPResponseCreationTime(), signature.getTrustedSigningTime()); } @Test public void dDocTimeMarkSignature_TrustedSigningTime_shouldReturnOCSPResponseCreationTime() { - this.configuration = Configuration.of(Configuration.Mode.TEST); - ConfigManagerInitializer.forceInitConfigManager(this.configuration); + configuration = Configuration.of(Configuration.Mode.TEST); + ConfigManagerInitializer.forceInitConfigManager(configuration); Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/ddoc_for_testing.ddoc"); Signature signature = container.getSignatures().get(0); Assert.assertNotNull(signature.getTrustedSigningTime()); @@ -353,7 +355,7 @@ public void dDocTimeMarkSignature_TrustedSigningTime_shouldReturnOCSPResponseCre @Test public void bDocTimeStampSignature_TrustedSigningTime_shouldReturnTimeStampCreationTime() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LT, + Signature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LT, pkcs12SignatureToken); Assert.assertNotNull(signature.getTrustedSigningTime()); Assert.assertEquals(signature.getTimeStampCreationTime(), signature.getTrustedSigningTime()); @@ -361,7 +363,7 @@ public void bDocTimeStampSignature_TrustedSigningTime_shouldReturnTimeStampCreat @Test public void bDocLTASignature_TrustedSigningTime_shouldReturnTimeStampCreationTime() { - Signature signature = this.createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LTA, + Signature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LTA, pkcs12SignatureToken); Assert.assertNotNull(signature.getTrustedSigningTime()); Assert.assertEquals(signature.getTimeStampCreationTime(), signature.getTrustedSigningTime()); @@ -379,10 +381,10 @@ public void getSignatureSigningCertificateDetails() { @Test public void gettingOcspCertificate_whenTslIsNotLoaded() { - this.configuration = new Configuration(Configuration.Mode.TEST); + configuration = new Configuration(Configuration.Mode.TEST); TSLCertificateSource certificateSource = new TSLCertificateSourceImpl(); - this.configuration.setTSL(certificateSource); - Container container = ContainerBuilder.aContainer().withConfiguration(this.configuration). + configuration.setTSL(certificateSource); + Container container = ContainerBuilder.aContainer().withConfiguration(configuration). fromExistingFile("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc").build(); Signature signature = container.getSignatures().get(0); Assert.assertNotNull(signature.getOCSPCertificate()); @@ -390,19 +392,19 @@ public void gettingOcspCertificate_whenTslIsNotLoaded() { @Test public void certificateContainsNotSupportedTssQcQualifier() { - this.configuration = new Configuration(Configuration.Mode.PROD); - Container container = this.openContainerByConfiguration( + configuration = new Configuration(Configuration.Mode.PROD); + Container container = openContainerByConfiguration( Paths.get("src/test/resources/prodFiles/invalid-containers/edoc2_lv-eId_sha256.edoc"), - this.configuration); + configuration); Assert.assertFalse(container.validate().isValid()); } @Test public void signatureReportForTwoSignature() { - this.configuration = new Configuration(Configuration.Mode.PROD); - Container container = this.openContainerByConfiguration( + configuration = new Configuration(Configuration.Mode.PROD); + Container container = openContainerByConfiguration( Paths.get("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"), - this.configuration); + configuration); SignatureValidationResult result = container.validate(); Assert.assertEquals(Indication.INDETERMINATE, result.getIndication("S0")); Assert.assertEquals(SubIndication.NO_CERTIFICATE_CHAIN_FOUND, result.getSubIndication("S0")); @@ -417,9 +419,9 @@ public void signatureReportForTwoSignature() { @Test public void signatureReportForOneSignature() { - this.configuration = new Configuration(Configuration.Mode.TEST); - Container container = this.openContainerByConfiguration( - Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"), this.configuration); + configuration = new Configuration(Configuration.Mode.TEST); + Container container = openContainerByConfiguration( + Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"), configuration); SignatureValidationResult result = container.validate(); for (SimpleReport signatureSimpleReport : result.getSimpleReports()) { for (String id : signatureSimpleReport.getSignatureIdList()) { @@ -436,10 +438,10 @@ public void signatureReportForOneSignature() { @Test public void signatureReportNoSignature() { - this.configuration = new Configuration(Configuration.Mode.TEST); - Container container = this.openContainerByConfiguration( + configuration = new Configuration(Configuration.Mode.TEST); + Container container = openContainerByConfiguration( Paths.get("src/test/resources/testFiles/valid-containers/container_without_signatures.bdoc"), - this.configuration); + configuration); SignatureValidationResult result = container.validate(); Assert.assertNull(result.getIndication("S0")); Assert.assertNull(result.getSubIndication("S0")); @@ -451,10 +453,10 @@ public void signatureReportNoSignature() { @Test public void signatureReportOnlyOneSignatureValid() { - this.configuration = new Configuration(Configuration.Mode.TEST); - Container container = this.openContainerByConfiguration( + configuration = new Configuration(Configuration.Mode.TEST); + Container container = openContainerByConfiguration( Paths.get("src/test/resources/testFiles/invalid-containers/two_signatures_one_invalid.bdoc"), - this.configuration); + configuration); SignatureValidationResult result = container.validate(); //Signature with id "S1" is invalid Assert.assertEquals(Indication.INDETERMINATE, result.getIndication("S1")); diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/ContainerSigningWithOutDataToSignSerializationTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/ContainerSigningWithOutDataToSignSerializationTest.java index 6d44f3c86..3979a6e95 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/ContainerSigningWithOutDataToSignSerializationTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/ContainerSigningWithOutDataToSignSerializationTest.java @@ -29,6 +29,9 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Date; import static org.digidoc4j.Container.DocumentType.ASICE; @@ -45,7 +48,7 @@ public void emptyBdocTwoStepSigning() { DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) + .withSignatureProfile(SignatureProfile.LT) .buildDataToSign(); ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -75,7 +78,7 @@ public void emptyBdocTwoStepSigning() { Signature signature = signatureFinalizer.finalizeSignature(signatureValue); container.addSignature(signature); - assertTimemarkSignature(signature); + assertTimestampSignature(signature); assertValidSignature(signature); SignatureValidationResult validationResult = container.validate(); @@ -98,7 +101,7 @@ public void emptyAsicETwoStepSigning() { byte[] signatureParametersSerialized = SerializationUtils.serialize(dataToSign.getSignatureParameters()); SignatureParameters signatureParameters = SerializationUtils.deserialize(signatureParametersSerialized); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); + byte[] signatureValue = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); container = ContainerBuilder.aContainer(ASICE) .withConfiguration(Configuration.getInstance()) @@ -120,10 +123,10 @@ public void emptyAsicETwoStepSigning() { @Test public void signedBDocTwoStepSigning() { - Container container = this.openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc")); + Container container = openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc")); DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) + .withSignatureProfile(SignatureProfile.LT) .buildDataToSign(); ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -132,7 +135,7 @@ public void signedBDocTwoStepSigning() { byte[] signatureParametersSerialized = SerializationUtils.serialize(dataToSign.getSignatureParameters()); SignatureParameters signatureParameters = SerializationUtils.deserialize(signatureParametersSerialized); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); + byte[] signatureValue = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); container = ContainerOpener.open(new ByteArrayInputStream(output.toByteArray()), Configuration.getInstance()); assertBDocContainer(container); @@ -141,7 +144,7 @@ public void signedBDocTwoStepSigning() { Signature signature = signatureFinalizer.finalizeSignature(signatureValue); container.addSignature(signature); - assertTimemarkSignature(signature); + assertTimestampSignature(signature); assertValidSignature(signature); SignatureValidationResult validationResult = container.validate(); @@ -151,7 +154,7 @@ public void signedBDocTwoStepSigning() { @Test public void signedAsicETwoStepSigning() { - Container container = this.openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-asice.asice")); + Container container = openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-asice.asice")); DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) .withSignatureProfile(SignatureProfile.LT) @@ -163,7 +166,7 @@ public void signedAsicETwoStepSigning() { byte[] signatureParametersSerialized = SerializationUtils.serialize(dataToSign.getSignatureParameters()); SignatureParameters signatureParameters = SerializationUtils.deserialize(signatureParametersSerialized); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); + byte[] signatureValue = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); container = ContainerOpener.open(new ByteArrayInputStream(output.toByteArray()), Configuration.getInstance()); assertAsicEContainer(container); @@ -182,17 +185,17 @@ public void signedAsicETwoStepSigning() { @Test public void twoStepSigningSigningTimeAssertion() throws InterruptedException { - Container container = this.openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc")); + Container container = openContainerBy(Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc")); // Signature object returned signing dates have milliseconds removed, truncated also from test data - long claimedSigningTimeLowerBound = new Date().getTime() / 1000 * 1000; + Instant claimedSigningTimeLowerBound = Instant.now().truncatedTo(ChronoUnit.SECONDS); DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) + .withSignatureProfile(SignatureProfile.LT) .buildDataToSign(); - long claimedSigningTimeUpperBound = new Date().getTime() + 1000; + Instant claimedSigningTimeUpperBound = Instant.now(); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); + byte[] signatureValue = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); ByteArrayOutputStream out = new ByteArrayOutputStream(); container.save(out); @@ -201,17 +204,16 @@ public void twoStepSigningSigningTimeAssertion() throws InterruptedException { // Artificial delay to make claimed signing time and actual signing time differ Thread.sleep(1000); - long trustedSigningTimeLowerBound = new Date().getTime() / 1000 * 1000; + Instant trustedSigningTimeLowerBound = Instant.now().truncatedTo(ChronoUnit.SECONDS); Signature signature = SignatureFinalizerBuilder.aFinalizer(container, dataToSign.getSignatureParameters()) .finalizeSignature(signatureValue); - long trustedSigningTimeUpperBound = new Date().getTime() + 1000; + Instant trustedSigningTimeUpperBound = Instant.now(); - long trustedSigningTime = signature.getTrustedSigningTime().getTime(); - assertTrue(trustedSigningTime >= trustedSigningTimeLowerBound); - assertTrue(trustedSigningTime <= trustedSigningTimeUpperBound); + Date trustedSigningTime = signature.getTrustedSigningTime(); + assertTimeInBounds(trustedSigningTime, trustedSigningTimeLowerBound, trustedSigningTimeUpperBound, Duration.ofSeconds(5)); - long claimedSigningTime = signature.getClaimedSigningTime().getTime(); - assertTrue(claimedSigningTime >= claimedSigningTimeLowerBound); - assertTrue(claimedSigningTime <= claimedSigningTimeUpperBound); + Date claimedSigningTime = signature.getClaimedSigningTime(); + assertTimeInBounds(claimedSigningTime, claimedSigningTimeLowerBound, claimedSigningTimeUpperBound, Duration.ZERO); } + } \ No newline at end of file diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/DataToSignSerializationTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/DataToSignSerializationTest.java index cde371ee9..ff72d302d 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/DataToSignSerializationTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/DataToSignSerializationTest.java @@ -10,9 +10,6 @@ package org.digidoc4j.impl; -import eu.europa.esig.dss.enumerations.DigestAlgorithm; -import eu.europa.esig.dss.enumerations.ObjectIdentifierQualifier; -import eu.europa.esig.dss.model.Policy; import org.apache.commons.lang3.SerializationUtils; import org.digidoc4j.AbstractTest; import org.digidoc4j.Configuration; @@ -24,19 +21,23 @@ import org.digidoc4j.Signature; import org.digidoc4j.SignatureBuilder; import org.digidoc4j.SignatureProfile; -import org.digidoc4j.ValidationResult; +import org.digidoc4j.impl.asic.asics.AsicSSignature; import org.junit.Ignore; import org.junit.Test; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Arrays; -import java.util.Date; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; // These tests might take long and are not necessary to be run in every build. @@ -78,7 +79,8 @@ public void finalizeSignature_emptyASICSContainer_dataFilesFromPath() { Container container = ContainerBuilder.aContainer(Container.DocumentType.ASICS).build(); container.addDataFile("src/test/resources/testFiles/helper-files/sized-files/" + fileSize + "KB.txt", "text/plain"); Signature signature = finalizeAndValidateContainerSignature(container, 0); - assertTimestampSignature(signature); + assertThat(signature, instanceOf(AsicSSignature.class)); + assertThat(signature.getProfile(), sameInstance(SignatureProfile.LT)); assertTrue(container.validate().isValid()); } } @@ -116,7 +118,8 @@ public void finalizeSignature_emptyASICSContainer_dataFilesAsStreams() throws Fi String fileName = fileSize + "KB.txt"; container.addDataFile(new FileInputStream("src/test/resources/testFiles/helper-files/sized-files/" + fileName), fileName, "text/plain"); Signature signature = finalizeAndValidateContainerSignature(container, fileSize * 1000); - assertTimestampSignature(signature); + assertThat(signature, instanceOf(AsicSSignature.class)); + assertThat(signature.getProfile(), sameInstance(SignatureProfile.LT)); assertTrue(container.validate().isValid()); } } @@ -172,46 +175,6 @@ public void finalizeSignature_notEmptyContainerFromStream() throws FileNotFoundE } } - @Test - public void customSignaturePolicyForBdoc() { - Policy customPolicy = new Policy(); - customPolicy.setId("SOME-ID"); - customPolicy.setSpuri("spuri"); - customPolicy.setQualifier(ObjectIdentifierQualifier.OID_AS_URN); - customPolicy.setDigestValue("some".getBytes(StandardCharsets.UTF_8)); - customPolicy.setDigestAlgorithm(DigestAlgorithm.SHA512); - - Container container = ContainerBuilder.aContainer(Container.DocumentType.BDOC).build(); - container.addDataFile("src/test/resources/testFiles/helper-files/sized-files/1KB.txt", "text/plain"); - - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) - .withOwnSignaturePolicy(customPolicy) - .buildDataToSign(); - - assertEquals(customPolicy, dataToSign.getSignatureParameters().getPolicy()); - byte[] signatureValue = pkcs12SignatureToken.sign(dataToSign.getDigestAlgorithm(), dataToSign.getDataToSign()); - Signature signature = dataToSign.finalize(signatureValue); - assertTimestampSignature(signature); - ValidationResult validationResult = signature.validateSignature(); - assertFalse(validationResult.isValid()); - assertEquals(1, validationResult.getWarnings().size()); - assertEquals("The signature/seal is an INDETERMINATE AdES digital signature!", validationResult.getWarnings().get(0).getMessage()); - assertEquals(2, validationResult.getErrors().size()); - assertEquals("The result of the LTV validation process is not acceptable to continue the process!", validationResult.getErrors().get(0).getMessage()); - } - - @Test - public void finalizeDetachedTimemarkSignature_dataFileFromStream() throws FileNotFoundException { - for (int fileSize : FILE_SIZES_IN_KILOBYTES) { - String fileName = fileSize + "KB.txt"; - DataFile dataFile = new DataFile(new FileInputStream("src/test/resources/testFiles/helper-files/sized-files/" + fileName), fileName, "text/plain"); - Signature signature = finalizeAndValidateDetachedSignature(dataFile, SignatureProfile.LT_TM, fileSize * 1000); - assertTimemarkSignature(signature); - } - } - @Test public void finalizeDetachedTimestampSignature_dataFileFromStream() throws FileNotFoundException { for (int fileSize : FILE_SIZES_IN_KILOBYTES) { @@ -248,25 +211,19 @@ private Signature finalizeAndValidateDetachedSignature(DataFile dataFile, Signat private Signature finalizeAndValidateSignature(DataToSign dataToSign, int dataFilesCount, int dataToSignAdditionalWeightInBytes) { byte[] dataToSignSerialized = SerializationUtils.serialize(dataToSign); - assertTrue(dataToSignAdditionalWeightInBytes + 20000 > dataToSignSerialized.length); - assertTrue(DATA_TO_SIGN_DIGEST_EXPECTED_CEILING_SIZE * dataFilesCount > dataToSign.getDataToSign().length); + assertThat(dataToSignSerialized.length, lessThan(dataToSignAdditionalWeightInBytes + 55000)); + assertThat(dataToSign.getDataToSign().length, lessThan(DATA_TO_SIGN_DIGEST_EXPECTED_CEILING_SIZE * dataFilesCount)); DataToSign dataToSignDeserialized = SerializationUtils.deserialize(dataToSignSerialized); byte[] signatureValue = pkcs12SignatureToken.sign(dataToSignDeserialized.getDigestAlgorithm(), dataToSignDeserialized.getDataToSign()); assertEquals(SIGNATURE_SIZE, signatureValue.length); - long trustedSigningTimeLowerBound = new Date().getTime() / 1000 * 1000; + Instant trustedSigningTimeLowerBound = Instant.now().truncatedTo(ChronoUnit.SECONDS); Signature signature = dataToSignDeserialized.finalize(signatureValue); - assertSigningTime(signature.getTrustedSigningTime(), trustedSigningTimeLowerBound); + assertTimeInBounds(signature.getTrustedSigningTime(), trustedSigningTimeLowerBound, Duration.ofSeconds(5)); assertValidSignature(signature); return signature; } - private void assertSigningTime(Date signingTime, long signingTimeLowerBound) { - long signingTimeUpperBound = new Date().getTime() + 1000; - long signingTimeSeconds = signingTime.getTime(); - assertTrue(signingTimeSeconds >= signingTimeLowerBound); - assertTrue(signingTimeSeconds <= signingTimeUpperBound); - } } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/EmptyDataFilesSignatureFinalizerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/EmptyDataFilesSignatureFinalizerTest.java index 2016c0a52..3ac7e5f52 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/EmptyDataFilesSignatureFinalizerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/EmptyDataFilesSignatureFinalizerTest.java @@ -1,3 +1,13 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.impl; import org.digidoc4j.AbstractTest; @@ -8,6 +18,7 @@ import org.junit.Test; import java.util.Arrays; +import java.util.Collections; import java.util.List; public abstract class EmptyDataFilesSignatureFinalizerTest extends AbstractTest { @@ -16,7 +27,7 @@ public abstract class EmptyDataFilesSignatureFinalizerTest extends AbstractTest @Test public void testCreateSignatureFinalizerWithSingleEmptyDataFile() { - List dataFiles = Arrays.asList( + List dataFiles = Collections.singletonList( new DataFile(new byte[0], "empty-file.txt", "text/plain") ); diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpenerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpenerTest.java new file mode 100644 index 000000000..aa8fda1d1 --- /dev/null +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/AsicESignatureOpenerTest.java @@ -0,0 +1,32 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asice; + +import org.digidoc4j.Signature; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpenerTest; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; + +public class AsicESignatureOpenerTest extends AsicXadesSignatureOpenerTest { + + @Override + protected AsicXadesSignatureOpener signatureOpener() { + return new AsicESignatureOpener(configuration); + } + + @Override + protected void assertSignatureType(Signature signature) { + assertThat(signature, instanceOf(AsicESignature.class)); + } + +} diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpenerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpenerTest.java new file mode 100644 index 000000000..78cd99b5c --- /dev/null +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asice/bdoc/BDocSignatureOpenerTest.java @@ -0,0 +1,32 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asice.bdoc; + +import org.digidoc4j.Signature; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpenerTest; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; + +public class BDocSignatureOpenerTest extends AsicXadesSignatureOpenerTest { + + @Override + protected AsicXadesSignatureOpener signatureOpener() { + return new BDocSignatureOpener(configuration); + } + + @Override + protected void assertSignatureType(Signature signature) { + assertThat(signature, instanceOf(BDocSignature.class)); + } + +} diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpenerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpenerTest.java new file mode 100644 index 000000000..9a5e0ee1f --- /dev/null +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/AsicSSignatureOpenerTest.java @@ -0,0 +1,32 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.impl.asic.asics; + +import org.digidoc4j.Signature; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpener; +import org.digidoc4j.impl.asic.xades.AsicXadesSignatureOpenerTest; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; + +public class AsicSSignatureOpenerTest extends AsicXadesSignatureOpenerTest { + + @Override + protected AsicXadesSignatureOpener signatureOpener() { + return new AsicSSignatureOpener(configuration); + } + + @Override + protected void assertSignatureType(Signature signature) { + assertThat(signature, instanceOf(AsicSSignature.class)); + } + +} diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicSignatureFinalizerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/EmptyDataFilesAsicSSignatureFinalizerTest.java similarity index 53% rename from digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicSignatureFinalizerTest.java rename to digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/EmptyDataFilesAsicSSignatureFinalizerTest.java index 57366661c..3be2aa944 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicSignatureFinalizerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/asics/EmptyDataFilesAsicSSignatureFinalizerTest.java @@ -1,18 +1,17 @@ -package org.digidoc4j.impl.bdoc.asic; +package org.digidoc4j.impl.asic.asics; import org.digidoc4j.DataFile; import org.digidoc4j.SignatureParameters; import org.digidoc4j.impl.EmptyDataFilesSignatureFinalizerTest; import org.digidoc4j.impl.SignatureFinalizer; -import org.digidoc4j.impl.asic.AsicSignatureFinalizer; import java.util.List; -public class EmptyDataFilesAsicSignatureFinalizerTest extends EmptyDataFilesSignatureFinalizerTest { +public class EmptyDataFilesAsicSSignatureFinalizerTest extends EmptyDataFilesSignatureFinalizerTest { @Override protected SignatureFinalizer createSignatureFinalizerWithDataFiles(List dataFiles) { - return new AsicSignatureFinalizer(dataFiles, new SignatureParameters(), configuration); + return new AsicSSignatureFinalizer(dataFiles, new SignatureParameters(), configuration); } } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSignatureOpenerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpenerTest.java similarity index 86% rename from digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSignatureOpenerTest.java rename to digidoc4j/src/test/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpenerTest.java index 21293b636..2e667a29e 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSignatureOpenerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/asic/xades/AsicXadesSignatureOpenerTest.java @@ -8,7 +8,7 @@ * Version 2.1, February 1999 */ -package org.digidoc4j.impl.bdoc; +package org.digidoc4j.impl.asic.xades; import eu.europa.esig.dss.model.DSSDocument; import eu.europa.esig.dss.model.FileDocument; @@ -21,10 +21,6 @@ import org.digidoc4j.Signature; import org.digidoc4j.SignatureProfile; import org.digidoc4j.impl.asic.AsicSignatureParser; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureOpener; -import org.digidoc4j.impl.asic.xades.XadesSignature; -import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import org.digidoc4j.utils.Helper; import org.junit.Assert; import org.junit.Test; @@ -33,16 +29,16 @@ import java.util.Collections; import java.util.Date; -public class BDocSignatureOpenerTest extends AbstractTest { +public abstract class AsicXadesSignatureOpenerTest extends AbstractTest { - private AsicSignatureParser signatureParser; - private BDocSignatureOpener signatureOpener; + protected abstract AsicXadesSignatureOpener signatureOpener(); + protected abstract void assertSignatureType(Signature signature); @Test public void openBesSignature() { - Signature signature = this.signatureOpener.open( + Signature signature = signatureOpener().open( constructXadesSignatureWrapper(new FileDocument("src/test/resources/testFiles/xades/test-bes-signature.xml"))); - Assert.assertTrue(signature instanceof BDocSignature); + assertSignatureType(signature); Assert.assertEquals(SignatureProfile.B_BES, signature.getProfile()); Assert.assertEquals("Assert 3", "id-693869a500c60f0dc262f7287f033d5d", signature.getId()); Assert.assertEquals("Assert 4", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", signature.getSignatureMethod()); @@ -69,8 +65,9 @@ public void openBesSignature() { public void openXadesSignature() { Date date_2016_29_1_time_19_58_36 = new Date(1454090316000L); Date date_2016_29_1_time_19_58_37 = new Date(1454090317000L); - Signature signature = this.signatureOpener.open( + Signature signature = signatureOpener().open( constructXadesSignatureWrapper(new FileDocument("src/test/resources/testFiles/xades/test-bdoc-ts.xml"))); + assertSignatureType(signature); Assert.assertNotNull("Assert 1", signature); Assert.assertEquals("Assert 2", "S0", signature.getId()); Assert.assertEquals("Assert 3", SignatureProfile.LT, signature.getProfile()); @@ -88,8 +85,9 @@ public void openXadesSignature() { @Test public void serializeBDocSignature() { - Signature signature = this.signatureOpener.open( + Signature signature = signatureOpener().open( constructXadesSignatureWrapper(new FileDocument("src/test/resources/testFiles/xades/test-bdoc-ts.xml"))); + assertSignatureType(signature); String serializedPath = this.getFileBy("ser"); Helper.serialize(signature, serializedPath); signature = Helper.deserializer(serializedPath); @@ -99,8 +97,9 @@ public void serializeBDocSignature() { @Test public void openXadesSignature_withoutXmlPreamble_shouldBeValid() throws Exception { byte[] signatureBytes = FileUtils.readFileToByteArray(new File("src/test/resources/testFiles/xades/bdoc-tm-jdigidoc-mobile-id.xml")); - Signature signature = this.signatureOpener.open( + Signature signature = signatureOpener().open( constructXadesSignatureWrapper(new InMemoryDocument(signatureBytes))); + assertSignatureType(signature); Assert.assertEquals("S935237", signature.getId()); } @@ -110,13 +109,12 @@ public void openXadesSignature_withoutXmlPreamble_shouldBeValid() throws Excepti @Override protected void before() { - this.configuration = Configuration.of(Configuration.Mode.TEST); - this.signatureOpener = new BDocSignatureOpener(this.configuration); - this.signatureParser = new AsicSignatureParser(Collections.singletonList( - new FileDocument("src/test/resources/testFiles/helper-files/test.txt")), this.configuration); + configuration = Configuration.of(Configuration.Mode.TEST); } private XadesSignatureWrapper constructXadesSignatureWrapper(DSSDocument document) { + AsicSignatureParser signatureParser = new AsicSignatureParser(Collections.singletonList( + new FileDocument("src/test/resources/testFiles/helper-files/test.txt")), this.configuration); XadesSignature signature = signatureParser.parse(document); return new XadesSignatureWrapper(signature, document); } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocContainerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocContainerTest.java index c61b8656f..cb6f601af 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocContainerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocContainerTest.java @@ -11,8 +11,6 @@ package org.digidoc4j.impl.bdoc; import eu.europa.esig.dss.DomUtils; -import eu.europa.esig.dss.enumerations.ObjectIdentifierQualifier; -import eu.europa.esig.dss.model.Policy; import eu.europa.esig.dss.validation.SignaturePolicy; import eu.europa.esig.dss.xades.validation.XAdESSignature; import org.apache.commons.codec.binary.Base64; @@ -34,18 +32,21 @@ import org.digidoc4j.SignatureBuilder; import org.digidoc4j.SignatureProfile; import org.digidoc4j.SignatureValidationResult; +import org.digidoc4j.exceptions.ContainerWithoutFilesException; +import org.digidoc4j.exceptions.DataFileNotFoundException; import org.digidoc4j.exceptions.DigiDoc4JException; import org.digidoc4j.exceptions.DuplicateDataFileException; import org.digidoc4j.exceptions.DuplicateSignatureFilesException; import org.digidoc4j.exceptions.IllegalSignatureProfileException; +import org.digidoc4j.exceptions.InvalidDataFileException; +import org.digidoc4j.exceptions.NotSupportedException; +import org.digidoc4j.exceptions.RemovingDataFileException; import org.digidoc4j.exceptions.TechnicalException; -import org.digidoc4j.impl.asic.AsicSignature; import org.digidoc4j.impl.asic.asice.AsicESignature; import org.digidoc4j.impl.asic.asice.bdoc.BDocContainer; import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; import org.digidoc4j.signers.PKCS12SignatureToken; import org.digidoc4j.test.TestAssert; -import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -57,6 +58,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -65,75 +67,92 @@ import java.util.List; import java.util.zip.ZipFile; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; + public class BDocContainerTest extends AbstractTest { @Test public void testSetDigestAlgorithmToSHA256() { - AsicESignature signature = this.createSignatureBy(DigestAlgorithm.SHA256, pkcs12SignatureToken); + AsicESignature signature = createSignatureBy(DigestAlgorithm.SHA256, pkcs12SignatureToken); Assert.assertEquals("http://www.w3.org/2001/04/xmlenc#sha256", signature.getSignatureDigestAlgorithm().getUri()); } @Test public void testSetDigestAlgorithmToSHA1() { - AsicESignature signature = this.createSignatureBy(DigestAlgorithm.SHA1, pkcs12SignatureToken); + AsicESignature signature = createSignatureBy(DigestAlgorithm.SHA1, pkcs12SignatureToken); Assert.assertEquals("http://www.w3.org/2000/09/xmldsig#sha1", signature.getSignatureDigestAlgorithm().getUri()); } @Test public void testSetDigestAlgorithmToSHA224() { - AsicESignature signature = this.createSignatureBy(DigestAlgorithm.SHA224, pkcs12SignatureToken); + AsicESignature signature = createSignatureBy(DigestAlgorithm.SHA224, pkcs12SignatureToken); Assert.assertEquals("http://www.w3.org/2001/04/xmldsig-more#sha224", signature.getSignatureDigestAlgorithm().getUri()); } @Test public void testDefaultDigestAlgorithm() { - AsicESignature signature = this.createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); + AsicESignature signature = createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); Assert.assertEquals("http://www.w3.org/2001/04/xmlenc#sha256", signature.getSignatureDigestAlgorithm().getUri()); } @Test public void testOpenBDocDocument() { - ContainerOpener.open("src/test/resources/testFiles/valid-containers/one_signature.bdoc").validate(); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/one_signature.bdoc"); + + assertThat(container.getSignatures(), hasSize(1)); } @Test public void testOpenBDocDocumentWithTwoSignatures() { - ContainerOpener.open("src/test/resources/testFiles/invalid-containers/two_signatures.bdoc").validate(); + Container container = ContainerOpener.open("src/test/resources/testFiles/invalid-containers/two_signatures.bdoc"); + + assertThat(container.getSignatures(), hasSize(2)); } - @Test(expected = DigiDoc4JException.class) + @Test public void testAddDataFileWhenFileDoesNotExist() { - this.createNonEmptyContainerBy(Paths.get("notExisting.txt"), "text/plain"); + assertThrows( + InvalidDataFileException.class, + () -> createNonEmptyContainerBy(Paths.get("notExisting.txt"), "text/plain") + ); } - @Test(expected = DigiDoc4JException.class) + @Test public void testAddDataFileFromInputStreamWithByteArrayConversionFailure() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); - container.addDataFile(new InputStream() { - - @Override - public int read() { - return 0; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - throw new IOException(); - } - - @Override - public void close() throws IOException { - throw new IOException(); - } - - }, "test.txt", "text/plain"); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); + assertThrows( + InvalidDataFileException.class, + () -> container.addDataFile(new InputStream() { + + @Override + public int read() { + return 0; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + throw new IOException(); + } + + @Override + public void close() throws IOException { + throw new IOException(); + } + + }, "test.txt", "text/plain") + ); } @Test public void testAddUnknownFileTypeKeepsMimeType() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.unknown_type"), "text/test_type"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.unknown_type"), "text/test_type"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals("text/test_type", container.getDataFiles().get(0).getMediaType()); @@ -141,10 +160,10 @@ public void testAddUnknownFileTypeKeepsMimeType() { @Test public void testSaveBDocDocumentWithTwoSignatures() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC); - this.createSignatureBy(container, pkcs12SignatureToken); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC); + createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); Assert.assertEquals(2, container.getSignatures().size()); Assert.assertEquals("6ec00b8b8c54c4f76082bd843e3a1526", @@ -161,8 +180,8 @@ public void testSaveBDocDocumentWithTwoSignatures() { @Test public void saveContainerWithoutSignatures() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getDataFiles().size()); @@ -176,7 +195,7 @@ public void openContainer_withoutSignatures_andAddMoreDataFiles() { container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); container.addDataFile("src/test/resources/testFiles/helper-files/word_file.docx", "application/octet-stream"); Assert.assertEquals(3, container.getDataFiles().size()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(3, container.getDataFiles().size()); @@ -184,7 +203,7 @@ public void openContainer_withoutSignatures_andAddMoreDataFiles() { @Test public void openContainerFromStream_withoutSignatures_andAddMoreDataFiles() throws Exception { - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); try (FileInputStream stream = new FileInputStream("src/test/resources/testFiles/valid-containers/container_without_signatures.bdoc")) { Container container = ContainerOpener.open(stream, false); Assert.assertEquals(1, container.getDataFiles().size()); @@ -204,10 +223,10 @@ public void openContainerWithoutSignatures_addDataFileAndSignContainer() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/container_without_signatures.bdoc"); Assert.assertEquals(1, container.getDataFiles().size()); container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals(1, container.getSignatures().size()); Assert.assertTrue(container.validate().isValid()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertTrue(container.validate().isValid()); @@ -215,9 +234,9 @@ public void openContainerWithoutSignatures_addDataFileAndSignContainer() { @Test public void testGetDefaultSignatureParameters() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Signature signature = container.getSignatures().get(0); @@ -225,31 +244,31 @@ public void testGetDefaultSignatureParameters() { Assert.assertEquals("", signature.getCity()); Assert.assertEquals("", signature.getStateOrProvince()); Assert.assertEquals("", signature.getCountryName()); - Assert.assertThat(signature.getSignerRoles(), Matchers.is(Matchers.empty())); + assertThat(signature.getSignerRoles(), empty()); } @Test public void getSignatureByIndex() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC); - this.createSignatureBy(container, pkcs12SignatureToken); - this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC); + createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals("6ec00b8b8c54c4f76082bd843e3a1526", container.getSignatures().get(1).getSigningCertificate().getSerial()); } @Test public void notThrowingNPEWhenDOCXFileIsAddedToContainer() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/word_file.docx"), "text/xml"); - this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/word_file.docx"), "text/xml"); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals(1, container.getSignatures().size()); } @Test public void signPdfDataFile() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/special-char-files/dds_acrobat.pdf"), "application/pdf"); - this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/special-char-files/dds_acrobat.pdf"), "application/pdf"); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals(1, container.getDataFiles().size()); Assert.assertEquals(1, container.getSignatures().size()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getDataFiles().size()); @@ -259,8 +278,8 @@ public void signPdfDataFile() { @Test public void testAddSignaturesToExistingDocument() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); Assert.assertEquals(3, container.getSignatures().size()); Assert.assertEquals("6ec00b8b8c54c4f76082bd843e3a1526", @@ -274,11 +293,11 @@ public void testAddSignaturesToExistingDocument() { @Test public void testRemoveSignatureWhenOneSignatureExists() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC); - this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC); + createSignatureBy(container, pkcs12SignatureToken); Signature signature = container.getSignatures().get(0); container.removeSignature(signature); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); Assert.assertEquals(0, container.getSignatures().size()); container = ContainerOpener.open(file); @@ -287,10 +306,9 @@ public void testRemoveSignatureWhenOneSignatureExists() { @Test public void testAddFilesWithSpecialCharactersIntoContainer() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/special-char-files/dds_dds_JÜRIÖÖ € žŠ päev.txt"), "text/plain"); - //container.addDataFile("src/test/resources/testFiles/special-char-files/dds_колючей стерне.docx", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - container.saveAsFile(this.getFileBy("bdoc")); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/special-char-files/dds_dds_JÜRIÖÖ € žŠ päev.txt"), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); + container.saveAsFile(getFileBy("bdoc")); Assert.assertEquals(0, container.validate().getContainerErrors().size()); } @@ -300,7 +318,7 @@ public void testRemoveSignatureWhenTwoSignaturesExist() { Assert.assertEquals(2, container.getSignatures().size()); Signature signature = container.getSignatures().get(0); container.removeSignature(signature); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getSignatures().size()); @@ -309,14 +327,14 @@ public void testRemoveSignatureWhenTwoSignaturesExist() { @Test public void testRemoveSignatureWhenThreeSignaturesExist() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(3, container.getSignatures().size()); Signature signature = container.getSignatures().get(1); container.removeSignature(signature); - file = this.getFileBy("bdoc"); + file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(2, container.getSignatures().size()); @@ -326,7 +344,7 @@ public void testRemoveSignatureWhenThreeSignaturesExist() { public void removeNewlyAddedSignatureFromExistingContainer() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); Assert.assertEquals(2, container.getSignatures().size()); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals(3, container.getSignatures().size()); container.removeSignature(container.getSignatures().get(0)); Assert.assertEquals(2, container.getSignatures().size()); @@ -338,7 +356,7 @@ public void removeSignatureFromExistingAsicEContainer() { Assert.assertEquals(2, container.getSignatures().size()); container.removeSignature(container.getSignatures().get(0)); Assert.assertEquals(1, container.getSignatures().size()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getSignatures().size()); @@ -350,7 +368,7 @@ public void removeSignatureFromExistingBDocTMContainer() { Assert.assertEquals(1, container.getSignatures().size()); container.removeSignature(container.getSignatures().get(0)); Assert.assertEquals(0, container.getSignatures().size()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(0, container.getSignatures().size()); @@ -366,96 +384,141 @@ public void removingNullSignatureDoesNothing() { @Test public void testSaveDocumentWithOneSignature() { - Assert.assertTrue(Files.exists(Paths.get(this.createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")))); + Assert.assertTrue(Files.exists(Paths.get(createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")))); } - @Test(expected = DigiDoc4JException.class) + @Test public void testRemoveDataFileAfterSigning() { - Container container = ContainerOpener.open(this.createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")); + Container container = ContainerOpener.open(createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")); Assert.assertEquals("test.txt", container.getDataFiles().get(0).getName()); Assert.assertEquals(1, container.getDataFiles().size()); - container.removeDataFile(container.getDataFiles().get(0)); - Assert.assertEquals(0, container.getDataFiles().size()); + DataFile dataFileToRemove = container.getDataFiles().get(0); + + RemovingDataFileException caughtException = assertThrows( + RemovingDataFileException.class, + () -> container.removeDataFile(dataFileToRemove) + ); + + assertThat(caughtException.getMessage(), equalTo("Datafiles cannot be removed from an already signed container")); } @Test public void testRemoveDataFile() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); Assert.assertEquals("test.txt", container.getDataFiles().get(0).getName()); Assert.assertEquals(1, container.getDataFiles().size()); container.removeDataFile(container.getDataFiles().get(0)); Assert.assertEquals(0, container.getDataFiles().size()); } - @Test(expected = DigiDoc4JException.class) + @Test public void testAddDataFileAfterSigning() { - Container container = ContainerOpener.open(this.createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); + Container container = ContainerOpener.open(createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")); + + DigiDoc4JException caughtException = assertThrows( + DigiDoc4JException.class, + () -> container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain") + ); + + assertThat(caughtException.getMessage(), equalTo("Datafiles cannot be added to an already signed container")); } - @Test(expected = DigiDoc4JException.class) + @Test public void testRemovingNonExistingFile() { - Container container = this.createNonEmptyContainer(); - container.removeDataFile(new DataFile(new byte[1], "test1.txt", "application/octet-stream")); + Container container = createNonEmptyContainer(); + DataFile dataFileToRemove = new DataFile(new byte[1], "test1.txt", "application/octet-stream"); + + DataFileNotFoundException caughtException = assertThrows( + DataFileNotFoundException.class, + () -> container.removeDataFile(dataFileToRemove) + ); + + assertThat(caughtException.getMessage(), equalTo("File not found: test1.txt")); } - @Test(expected = DuplicateDataFileException.class) + @Test public void testAddingSameFileSeveralTimes() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + + DuplicateDataFileException caughtException = assertThrows( + DuplicateDataFileException.class, + () -> container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain") + ); + + assertThat(caughtException.getMessage(), equalTo("Data file test.txt already exists")); } - @Test(expected = DuplicateDataFileException.class) + @Test public void testAddingSamePreCreatedFileSeveralTimes() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); DataFile dataFile = new DataFile("Hello world!".getBytes(), "test-file.txt", "text/plain"); container.addDataFile(dataFile); - container.addDataFile(dataFile); + + DuplicateDataFileException caughtException = assertThrows( + DuplicateDataFileException.class, + () -> container.addDataFile(dataFile) + ); + + assertThat(caughtException.getMessage(), equalTo("Data file test-file.txt already exists")); } @Test public void testAddingDifferentPreCreatedFiles() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile(new DataFile("Hello world!".getBytes(), "hello.txt", "text/plain")); container.addDataFile(new DataFile("Goodbye world!".getBytes(), "goodbye.txt", "text/plain")); } - @Test(expected = DuplicateDataFileException.class) + @Test public void testAddingSameFileSeveralTimesViaInputStream() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); - container.addDataFile(new ByteArrayInputStream("test".getBytes()), "src/test/resources/testFiles/helper-files/test.txt", "text/plain"); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile(new ByteArrayInputStream("test".getBytes()), "src/test/resources/testFiles/helper-files/test.txt", "text/plain"); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("test".getBytes()); + + DuplicateDataFileException caughtException = assertThrows( + DuplicateDataFileException.class, + () -> container.addDataFile(byteArrayInputStream, "src/test/resources/testFiles/helper-files/test.txt", "text/plain") + ); + + assertThat(caughtException.getMessage(), equalTo("Data file test.txt already exists")); } @Test public void testAddDateFileViaInputStream() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile(new ByteArrayInputStream("test".getBytes()), "src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertTrue(container.validate().isValid()); } - @Test(expected = DuplicateDataFileException.class) + @Test public void testAddingSameFileInDifferentContainerSeveralTimes() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - container.saveAsFile(this.getFileBy("bdoc")); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + + DuplicateDataFileException caughtException = assertThrows( + DuplicateDataFileException.class, + () -> container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain") + ); + + assertThat(caughtException.getMessage(), equalTo("Data file test.txt already exists")); } - @Test(expected = DigiDoc4JException.class) + @Test public void testAddingNotExistingFile() { - this.createNonEmptyContainerBy(Paths.get("notExistingFile.txt"), "text/plain"); + assertThrows( + InvalidDataFileException.class, + () -> createNonEmptyContainerBy(Paths.get("notExistingFile.txt"), "text/plain") + ); } @Test public void testAddFileAsStream() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); ByteArrayInputStream stream = new ByteArrayInputStream("tere, tere".getBytes()); container.addDataFile(stream, "test1.txt", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); Container containerToTest = ContainerOpener.open(file); Assert.assertEquals("test1.txt", containerToTest.getDataFiles().get(0).getName()); @@ -463,14 +526,14 @@ public void testAddFileAsStream() { @Test public void setsSignatureId() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); Signature signature1 = SignatureBuilder.aSignature(container).withSignatureId("SIGNATURE-1"). withSignatureToken(pkcs12SignatureToken).invokeSigning(); container.addSignature(signature1); Signature signature2 = SignatureBuilder.aSignature(container).withSignatureId("SIGNATURE-2"). withSignatureToken(pkcs12SignatureToken).invokeSigning(); container.addSignature(signature2); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals("SIGNATURE-1", container.getSignatures().get(0).getId()); @@ -483,10 +546,10 @@ public void setsSignatureId() throws Exception { @Test public void setsDefaultSignatureId() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); String signature1Id = container.getSignatures().get(0).getId(); @@ -502,21 +565,32 @@ public void setsDefaultSignatureId() throws Exception { @Test public void getDataFileByIndex() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals("test.txt", container.getDataFiles().get(0).getName()); } - @Test(expected = DigiDoc4JException.class) + @Test public void openNonExistingFileThrowsError() { - ContainerOpener.open("non-existing.bdoc"); + DigiDoc4JException caughtException = assertThrows( + DigiDoc4JException.class, + () -> ContainerOpener.open("non-existing.bdoc") + ); + + assertThat(caughtException.getCause(), instanceOf(FileNotFoundException.class)); } - @Test(expected = DigiDoc4JException.class) + @Test public void openClosedStreamThrowsException() throws IOException { try (FileInputStream stream = new FileInputStream("src/test/resources/testFiles/helper-files/test.txt")) { stream.close(); - ContainerOpener.open(stream, false); + + DigiDoc4JException caughtException = assertThrows( + DigiDoc4JException.class, + () -> ContainerOpener.open(stream, false) + ); + + assertThat(caughtException.getCause(), instanceOf(IOException.class)); } } @@ -525,8 +599,8 @@ public void testLargeFileSigning() { BDocContainer container = (BDocContainer) ContainerBuilder.aContainer(Container.DocumentType.BDOC) .withConfiguration(new Configuration(Configuration.Mode.TEST)).build(); container.getConfiguration().setMaxFileSizeCachedInMemoryInMB(10); - container.addDataFile(this.createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100), "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + container.addDataFile(createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); } @Test @@ -534,9 +608,9 @@ public void openLargeFileFromStream() throws IOException { BDocContainer container = (BDocContainer) ContainerBuilder.aContainer(Container.DocumentType.BDOC). withConfiguration(new Configuration(Configuration.Mode.TEST)).build(); container.getConfiguration().setMaxFileSizeCachedInMemoryInMB(0); - String file = this.createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100); + String file = createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100); container.addDataFile(file, "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); container.saveAsFile(file); try (FileInputStream stream = new FileInputStream(file)) { ContainerOpener.open(stream, true); @@ -546,12 +620,12 @@ public void openLargeFileFromStream() throws IOException { @Test public void openAddFileFromStream() throws IOException { - BDocContainer container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + BDocContainer container = createEmptyContainerBy(Container.DocumentType.BDOC); container.getConfiguration().setMaxFileSizeCachedInMemoryInMB(0); - String file = this.createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100); + String file = createNonEmptyLargeContainer(container.getConfiguration().getMaxDataFileCachedInBytes() + 100); try (FileInputStream stream = new FileInputStream(file)) { container.addDataFile(stream, "fileName", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); container.saveAsFile(file); FileInputStream stream2 = new FileInputStream(file); ContainerOpener.open(stream2, true); @@ -562,13 +636,13 @@ public void openAddFileFromStream() throws IOException { @Test public void testGetDocumentType() { - Container container = ContainerOpener.open(this.createSignedContainerBy(Container.DocumentType.BDOC, "bdoc")); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"); Assert.assertEquals(Constant.BDOC_CONTAINER_TYPE, container.getType()); } @Test public void testAddTwoFilesAsStream() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); ByteArrayInputStream stream = new ByteArrayInputStream("tere, tere".getBytes()); stream.mark(Integer.MAX_VALUE); container.addDataFile(stream, "test1.txt", "text/plain"); @@ -578,11 +652,11 @@ public void testAddTwoFilesAsStream() { @Test public void testAddTwoFilesAsFileWithoutOCSP() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); - this.createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(2, container.getDataFiles().size()); @@ -590,10 +664,10 @@ public void testAddTwoFilesAsFileWithoutOCSP() { @Test public void testGetFileNameAndID() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals("test.txt", container.getDataFiles().get(0).getName()); @@ -604,10 +678,10 @@ public void testGetFileNameAndID() { @Test public void testAddTwoFilesAsFileWithOCSP() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(2, container.getDataFiles().size()); @@ -615,10 +689,10 @@ public void testAddTwoFilesAsFileWithOCSP() { @Test public void saveToStream() throws Exception { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile(new ByteArrayInputStream(new byte[]{0x42}), "test_bytes.txt", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - File expectedContainerAsFile = new File(this.getFileBy("bdoc")); + createSignatureBy(container, pkcs12SignatureToken); + File expectedContainerAsFile = new File(getFileBy("bdoc")); try (OutputStream out = Files.newOutputStream(expectedContainerAsFile.toPath())) { container.save(out); } @@ -630,7 +704,7 @@ public void saveToStream() throws Exception { @Test public void saveExistingContainerToStream() throws Exception { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Assert.assertEquals(3, container.getSignatures().size()); InputStream inputStream = container.saveAsStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -641,21 +715,27 @@ public void saveExistingContainerToStream() throws Exception { Assert.assertEquals(1, container.getDataFiles().size()); } - @Test(expected = DigiDoc4JException.class) + @Test public void saveToStreamThrowsException() throws IOException { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - File expectedContainerAsFile = new File(this.getFileBy("bdoc")); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); + File expectedContainerAsFile = new File(getFileBy("bdoc")); try (OutputStream out = Files.newOutputStream(expectedContainerAsFile.toPath())) { out.close(); - container.save(out); + + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> container.save(out) + ); + + assertThat(caughtException.getMessage(), equalTo("Unable to write Zip entry to asic container")); } } @Test public void saveExistingContainer() throws Exception { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); - String file = this.getFileBy("asice"); + String file = getFileBy("asice"); container.saveAsFile(file); Container savedContainer = ContainerOpener.open(file); Assert.assertTrue(savedContainer.validate().isValid()); @@ -672,26 +752,33 @@ public void saveExistingContainer() throws Exception { @Test public void containerIsLT() { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getSignatures().size()); Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); } - @Test(expected = DigiDoc4JException.class) + @Test public void signWithoutDataFile() { - this.createSignatureBy(this.createEmptyContainerBy(Container.DocumentType.BDOC, Container.class), pkcs12SignatureToken); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC, Container.class); + + ContainerWithoutFilesException caughtException = assertThrows( + ContainerWithoutFilesException.class, + () -> createSignatureBy(container, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), equalTo("Container does not contain any data files")); } @Test public void nonStandardMimeType() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/newtype"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); SignatureValidationResult result = container.validate(); @@ -701,20 +788,20 @@ public void nonStandardMimeType() { @Test public void twoStepSigning() throws IOException { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); DataToSign dataToSign = SignatureBuilder.aSignature(container). withSigningCertificate(pkcs12SignatureToken.getCertificate()).buildDataToSign(); - Signature signature = dataToSign.finalize(this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm())); + Signature signature = dataToSign.finalize(sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm())); container.addSignature(signature); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertTrue(container.validate().isValid()); Assert.assertEquals(1, container.getSignatures().size()); Signature resultSignature = container.getSignatures().get(0); Assert.assertEquals("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", resultSignature.getSignatureMethod()); - Assert.assertThat(resultSignature.getSignerRoles(), Matchers.is(Matchers.empty())); + assertThat(resultSignature.getSignerRoles(), empty()); Assert.assertEquals("", resultSignature.getCity()); Assert.assertTrue(StringUtils.isNotBlank(resultSignature.getId())); Assert.assertNotNull(resultSignature.getOCSPCertificate()); @@ -741,10 +828,10 @@ public void twoStepSigningVerifySignatureParameters() { withSignatureDigestAlgorithm(DigestAlgorithm.SHA512).withSigningCertificate(pkcs12SignatureToken.getCertificate()). withSignatureId("S99").withRoles("manager", "employee").withCity("city").withStateOrProvince("state"). withPostalCode("postalCode").withCountry("country").buildDataToSign(); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); + byte[] signatureValue = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); Signature signature = dataToSign.finalize(signatureValue); container.addSignature(signature); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); container = ContainerOpener.open(file); Assert.assertEquals(1, container.getSignatures().size()); @@ -757,33 +844,38 @@ public void twoStepSigningVerifySignatureParameters() { @Test public void testContainerCreationAsTSA() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken); Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); } @Test public void testBDocTM() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); - Assert.assertTrue(container.validate().isValid()); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString("Can't create LT_TM signatures")); } @Test public void testBDocTS() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); Assert.assertTrue(container.validate().isValid()); } @Test public void containerWithBESProfileHasNoValidationErrors() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); Assert.assertEquals(SignatureProfile.B_BES, container.getSignatures().get(0).getProfile()); Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); Assert.assertFalse(container.validate().isValid()); @@ -791,7 +883,7 @@ public void containerWithBESProfileHasNoValidationErrors() { @Test public void signWithECCCertificate() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC); Signature signature = SignatureBuilder.aSignature(container). withSignatureToken(new PKCS12SignatureToken("src/test/resources/testFiles/p12/MadDogOY.p12", "test".toCharArray())). withEncryptionAlgorithm(EncryptionAlgorithm.ECDSA).invokeSigning(); @@ -802,9 +894,9 @@ public void signWithECCCertificate() { @Test public void zipFileComment() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); String expectedComment = Constant.USER_AGENT_STRING; try (ZipFile zipFile = new ZipFile(file)) { @@ -818,13 +910,13 @@ public void zipFileComment() throws Exception { @Test public void signingMoreThanTwoFiles() { - Container container = this.createNonEmptyContainerBy(Container.DocumentType.BDOC, + Container container = createNonEmptyContainerBy(Container.DocumentType.BDOC, Paths.get("src/test/resources/testFiles/special-char-files/dds_dds_JÜRIÖÖ € žŠ päev.txt"), "text/plain"); container.addDataFile("src/test/resources/testFiles/special-char-files/dds_pakitud.zip", "text/plain"); container.addDataFile("src/test/resources/testFiles/special-char-files/dds_SK.jpg", "text/plain"); container.addDataFile("src/test/resources/testFiles/special-char-files/dds_acrobat.pdf", "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); Signature signature = container.getSignatures().get(0); TestAssert.assertSignatureMetadataContainsFileName(signature, "dds_dds_JÜRIÖÖ € žŠ päev.txt"); TestAssert.assertSignatureMetadataContainsFileName(signature, "dds_pakitud.zip"); @@ -834,11 +926,11 @@ public void signingMoreThanTwoFiles() { @Test public void signatureFileNamesShouldBeInSequence() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); - this.createSignatureBy(container, pkcs12SignatureToken); - this.createSignatureBy(container, pkcs12SignatureToken); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + Container container = createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt"), "text/plain"); + createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); try (ZipFile zip = new ZipFile(file)) { Assert.assertNotNull(zip.getEntry("META-INF/signatures0.xml")); @@ -854,8 +946,8 @@ public void whenSigningExistingContainer_withTwoSignatures_shouldCreateSignature Assert.assertNotNull(zip.getEntry("META-INF/signatures1.xml")); } Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/asics_testing_two_signatures.bdoc"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); try (ZipFile zip = new ZipFile(file)) { Assert.assertNotNull(zip.getEntry("META-INF/signatures0.xml")); @@ -871,8 +963,8 @@ public void whenSigningExistingContainer_with_signatures1_xml_shouldCreateSignat Assert.assertNotNull(zip.getEntry("META-INF/signatures1.xml")); } Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/DigiDocService_spec_est.pdf-TM-j.bdoc"); - this.createSignatureBy(container, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); try (ZipFile zip = new ZipFile(file)) { Assert.assertNull(zip.getEntry("META-INF/signatures0.xml")); @@ -881,15 +973,21 @@ public void whenSigningExistingContainer_with_signatures1_xml_shouldCreateSignat } } - @Test(expected = TechnicalException.class) + @Test public void addSignatureWithDuplicateSignatureId_throwsException() { Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/test.asice"); Signature signature = SignatureBuilder.aSignature(container). withSignatureToken(pkcs12SignatureToken).withSignatureId("S0").invokeSigning(); - container.addSignature(signature); + + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> container.addSignature(signature) + ); + + assertThat(caughtException.getMessage(), equalTo("Signature with Id \"S0\" already exists")); } - @Test(expected = IllegalSignatureProfileException.class) + @Test public void addTimemarkSignatureToAsicEContainer_throwsException() { Container bdocContainer = ContainerOpener.open(BDOC_WITH_TM_SIG); Signature timemarkSignature = bdocContainer.getSignatures().get(0); @@ -897,10 +995,18 @@ public void addTimemarkSignatureToAsicEContainer_throwsException() { Container asicEContainer = ContainerOpener.open(ASICE_WITH_TS_SIG); assertAsicEContainer(asicEContainer); - asicEContainer.addSignature(timemarkSignature); + + IllegalSignatureProfileException caughtException = assertThrows( + IllegalSignatureProfileException.class, + () -> asicEContainer.addSignature(timemarkSignature) + ); + + assertThat(caughtException.getMessage(), equalTo( + "Cannot add BDoc specific (LT_TM) signature to ASiCE container" + )); } - @Test(expected = IllegalSignatureProfileException.class) + @Test public void addBEpesSignatureToAsicEContainer_throwsException() { Container bdocContainer = ContainerOpener.open(BDOC_WITH_B_EPES_SIG); Signature bEpesSignature = bdocContainer.getSignatures().get(0); @@ -908,7 +1014,15 @@ public void addBEpesSignatureToAsicEContainer_throwsException() { Container asicEContainer = ContainerOpener.open(ASICE_WITH_TS_SIG); assertAsicEContainer(asicEContainer); - asicEContainer.addSignature(bEpesSignature); + + IllegalSignatureProfileException caughtException = assertThrows( + IllegalSignatureProfileException.class, + () -> asicEContainer.addSignature(bEpesSignature) + ); + + assertThat(caughtException.getMessage(), equalTo( + "Cannot add BDoc specific (B_EPES) signature to ASiCE container" + )); } @Test @@ -919,9 +1033,9 @@ public void whenSigningContainer_withSignatureNameContainingNonNumericCharacters Assert.assertNull(zip.getEntry("META-INF/signatures1.xml")); } Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-ts-signature-file-name-with-non-numeric-characters.asice"); - this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); - this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); - String file = this.getFileBy("bdoc"); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + String file = getFileBy("bdoc"); container.saveAsFile(file); try (ZipFile zip = new ZipFile(file)) { Assert.assertNotNull(zip.getEntry("META-INF/l77Tsignaturesn00B.xml")); @@ -930,18 +1044,32 @@ public void whenSigningContainer_withSignatureNameContainingNonNumericCharacters } } - @Test(expected = DigiDoc4JException.class) + @Test public void whenOpeningContainer_withTwoDataFilesWithSameName_andWithSingleReferenceInManifest_shouldThrowException() { - ContainerBuilder.aContainer() + ContainerBuilder containerBuilder = ContainerBuilder.aContainer() .fromExistingFile("src/test/resources/testFiles/invalid-containers/KS-19_IB-3721_bdoc21-TM-2fil-samename-1sig3.bdoc") - .withConfiguration(new Configuration(Configuration.Mode.TEST)).build(); + .withConfiguration(new Configuration(Configuration.Mode.TEST)); + + DuplicateDataFileException caughtException = assertThrows( + DuplicateDataFileException.class, + containerBuilder::build + ); + + assertThat(caughtException.getMessage(), equalTo("Container contains duplicate data file: readme.txt")); } - @Test(expected = DigiDoc4JException.class) + @Test public void whenOpeningContainer_withTwoManifests_oneIsErroneous_shouldThrowException() { - ContainerBuilder.aContainer() + ContainerBuilder containerBuilder = ContainerBuilder.aContainer() .fromExistingFile("src/test/resources/testFiles/invalid-containers/KS-10_manifest_topelt_bdoc21_TM.bdoc") - .withConfiguration(new Configuration(Configuration.Mode.TEST)).build(); + .withConfiguration(new Configuration(Configuration.Mode.TEST)); + + DigiDoc4JException caughtException = assertThrows( + DigiDoc4JException.class, + containerBuilder::build + ); + + assertThat(caughtException.getMessage(), equalTo("Multiple manifest.xml files disallowed")); } @Test @@ -952,11 +1080,18 @@ public void whenExistingContainer_hasWrongMimeSlash_weShouldNotThrowException() Assert.assertFalse("Container is not invalid", result.isValid()); } - @Test(expected = DigiDoc4JException.class) + @Test public void whenOpeningContainer_withSignatureInfo_butNoSignedDataObject_shouldThrowException() { - ContainerBuilder.aContainer() + ContainerBuilder containerBuilder = ContainerBuilder.aContainer() .fromExistingFile("src/test/resources/testFiles/invalid-containers/3863_bdoc21_TM_no_datafile.bdoc") - .withConfiguration(new Configuration(Configuration.Mode.TEST)).build(); + .withConfiguration(new Configuration(Configuration.Mode.TEST)); + + ContainerWithoutFilesException caughtException = assertThrows( + ContainerWithoutFilesException.class, + containerBuilder::build + ); + + assertThat(caughtException.getMessage(), equalTo("The reference data object(s) is not found!")); } @Test @@ -981,20 +1116,19 @@ public void containerWithImplicitPolicy(){ @Test public void bdocTM_OcspResponderCert_shouldContainResponderCertIdAttribute() { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - BDocSignature signature = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); - Assert.assertEquals(1, this.countOCSPResponderCertificates(signature.getOrigin().getDssSignature())); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"); + BDocSignature signature = (BDocSignature) container.getSignatures().get(0); + Assert.assertEquals(1, countOCSPResponderCertificates(signature.getOrigin().getDssSignature())); } @Test public void savingContainerWithoutSignatures_shouldNotThrowException() throws Exception { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + Container container = createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); Assert.assertTrue(container.getSignatures().isEmpty()); Assert.assertEquals(1, container.getDataFiles().size()); Assert.assertTrue(container.validate().isValid()); - String file = this.getFileBy("bdoc"); + String file = getFileBy("bdoc"); container.saveAsFile(file); Container savedContainer = ContainerOpener.open(file); Assert.assertTrue(savedContainer.getSignatures().isEmpty()); @@ -1006,10 +1140,10 @@ public void savingContainerWithoutSignatures_shouldNotThrowException() throws Ex @Test public void openBDoc_withoutCAConfiguration_shouldNotThrowException() { - this.configuration = new Configuration(Configuration.Mode.TEST); - this.configuration.loadConfiguration("src/test/resources/testFiles/yaml-configurations/digidoc_test_conf_no_ca.yaml"); - Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc", this.configuration); - MatcherAssert.assertThat(container, Matchers.instanceOf(BDocContainer.class)); + configuration = new Configuration(Configuration.Mode.TEST); + configuration.loadConfiguration("src/test/resources/testFiles/yaml-configurations/digidoc_test_conf_no_ca.yaml"); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc", configuration); + assertThat(container, Matchers.instanceOf(BDocContainer.class)); Assert.assertTrue(container.validate().isValid()); } @@ -1022,46 +1156,9 @@ public void timeStampCertStatusDeprecated() { Assert.assertFalse(container.validate().isValid()); } - @Test - public void settingUpOwnSignaturePolicy() { - String signatureId = "signatureId"; - byte[] digestValue = Base64.decodeBase64("3Tl1oILSvOAWomdI9VeWV6IA/32eSXRUri9kPEz1IVs="); - ObjectIdentifierQualifier qualifier = ObjectIdentifierQualifier.OID_AS_URN; - eu.europa.esig.dss.enumerations.DigestAlgorithm digestAlgorithm = eu.europa.esig.dss.enumerations.DigestAlgorithm.SHA256; - String spuri = "spuri"; - Policy signaturePolicy = new Policy(); - signaturePolicy.setId(signatureId); - signaturePolicy.setDigestValue(digestValue); - signaturePolicy.setQualifier(qualifier); - signaturePolicy.setDigestAlgorithm(digestAlgorithm); - signaturePolicy.setSpuri(spuri); - Container container = ContainerBuilder.aContainer(Container.DocumentType.BDOC).build(); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - Signature signature = SignatureBuilder.aSignature(container).withOwnSignaturePolicy(signaturePolicy). - withSignatureDigestAlgorithm(DigestAlgorithm.SHA224).withSignatureToken(pkcs12SignatureToken). - withSignatureProfile(SignatureProfile.LT_TM).invokeSigning(); - container.addSignature(signature); - String file = this.getFileBy("bdoc"); - container.saveAsFile(file); - container = ContainerOpener.open(file); - AsicSignature asicSignature = (AsicSignature) container.getSignatures().get(0); - SignaturePolicy policyId = asicSignature.getOrigin().getDssSignature().getSignaturePolicy(); - Assert.assertEquals(spuri, policyId.getUri()); - Assert.assertEquals(signatureId, policyId.getIdentifier()); - Assert.assertEquals(digestAlgorithm, policyId.getDigest().getAlgorithm()); - Assert.assertArrayEquals(Base64.decodeBase64("3Tl1oILSvOAWomdI9VeWV6IA/32eSXRUri9kPEz1IVs="), policyId.getDigest().getValue()); - } - @Test public void containerWithSignaturePolicyByDefault() { - Container container = ContainerBuilder.aContainer(Container.DocumentType.BDOC).build(); - container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - Signature signature = SignatureBuilder.aSignature(container).withSignatureDigestAlgorithm(DigestAlgorithm.SHA224). - withSignatureToken(pkcs12SignatureToken).withSignatureProfile(SignatureProfile.LT_TM).invokeSigning(); - container.addSignature(signature); - String file = this.getFileBy("bdoc"); - container.saveAsFile(file); - container = ContainerOpener.open(file); + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"); BDocSignature bdocSignature = (BDocSignature) container.getSignatures().get(0); SignaturePolicy policyId = bdocSignature.getOrigin().getDssSignature().getSignaturePolicy(); Assert.assertEquals("https://www.sk.ee/repository/bdoc-spec21.pdf", policyId.getUri()); @@ -1106,7 +1203,7 @@ public void containerWithMultipleIdenticallyNamedSignaturesShouldFail() { */ private int countOCSPResponderCertificates(XAdESSignature signature) { - return this.countResponderCertIdInsCertificateValues(DomUtils.getElement(signature.getSignatureElement(), + return countResponderCertIdInsCertificateValues(DomUtils.getElement(signature.getSignatureElement(), signature.getXAdESPaths().getCertificateValuesPath())); } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSerializationTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSerializationTest.java index a5980fd7b..3c1214f0b 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSerializationTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/BDocSerializationTest.java @@ -24,12 +24,17 @@ import org.digidoc4j.SignatureValidationResult; import org.digidoc4j.exceptions.ServiceUnreachableException; import org.digidoc4j.test.util.TestDataBuilderUtil; -import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import java.util.Date; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.startsWith; + public class BDocSerializationTest extends AbstractTest { private String containerLocation; @@ -40,8 +45,9 @@ public void twoStepSigningWithSerialization() { String serializedDataToSignPath = this.getFileBy("bdoc"); Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - DataToSign dataToSign = SignatureBuilder.aSignature(container). - withSigningCertificate(pkcs12SignatureToken.getCertificate()).buildDataToSign(); + DataToSign dataToSign = SignatureBuilder.aSignature(container) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()) + .buildDataToSign(); this.serialize(container, this.serializedContainerLocation); this.serialize(dataToSign, serializedDataToSignPath); dataToSign = this.deserializer(serializedDataToSignPath); @@ -56,20 +62,26 @@ public void twoStepSigningWithSerialization() { Assert.assertEquals(1, container.getSignatures().size()); } - @Test(expected = ServiceUnreachableException.class) + @Test public void changeConfigurationAfterDeserializationToInvalidOcspAndThrowConnectionFailureException(){ String serializedDataToSignPath = this.getFileBy("bdoc"); Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - DataToSign dataToSign = SignatureBuilder.aSignature(container). - withSigningCertificate(pkcs12SignatureToken.getCertificate()).buildDataToSign(); + DataToSign originalDataToSign = SignatureBuilder.aSignature(container) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()) + .buildDataToSign(); this.serialize(container, this.serializedContainerLocation); - this.serialize(dataToSign, serializedDataToSignPath); - dataToSign = this.deserializer(serializedDataToSignPath); - dataToSign.getConfiguration().setOcspSource("http://invalid.ocsp.url"); + this.serialize(originalDataToSign, serializedDataToSignPath); + DataToSign deserializedDataToSign = this.deserializer(serializedDataToSignPath); + deserializedDataToSign.getConfiguration().setOcspSource("http://invalid.ocsp.url"); + byte[] signatureValue = this.sign(deserializedDataToSign.getDataToSign(), deserializedDataToSign.getDigestAlgorithm()); - byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); - dataToSign.finalize(signatureValue); + ServiceUnreachableException caughtException = assertThrows( + ServiceUnreachableException.class, + () -> deserializedDataToSign.finalize(signatureValue) + ); + + assertThat(caughtException.getMessage(), containsString("Failed to connect to OCSP service")); } @Test @@ -129,8 +141,8 @@ public void serializationVerifyDefaultSignatureParameters() { Container deserializedContainer = this.deserializer(this.serializedContainerLocation); Signature signature = deserializedContainer.getSignatures().get(0); Assert.assertEquals("", signature.getCity()); - Assert.assertThat(signature.getSignerRoles(), Matchers.is(Matchers.empty())); - Assert.assertTrue(signature.getId().startsWith("id-")); + assertThat(signature.getSignerRoles(), empty()); + assertThat(signature.getId(), startsWith("id-")); Assert.assertEquals("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", signature.getSignatureMethod()); } @@ -264,7 +276,6 @@ public void twoStepSigningWithSerialization2() { DataToSign dataToSign = SignatureBuilder.aSignature(container) .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) .buildDataToSign(); byte[] serializedDataToSign = SerializationUtils.serialize(dataToSign); @@ -272,7 +283,7 @@ public void twoStepSigningWithSerialization2() { byte[] signatureValue = this.sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); Signature signature = dataToSign.finalize(signatureValue); - assertTimemarkSignature(signature); + assertTimestampSignature(signature); assertValidSignature(signature); container.addSignature(signature); @@ -280,7 +291,7 @@ public void twoStepSigningWithSerialization2() { container = ContainerOpener.open(this.containerLocation); SignatureValidationResult validationResult = container.validate(); Assert.assertTrue(validationResult.isValid()); - Assert.assertEquals(1, container.getSignatures().size()); + assertThat(container.getSignatures(), hasSize(1)); } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ContainerParticlesRemovalTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ContainerParticlesRemovalTest.java index 3f55443ef..e7133ca87 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ContainerParticlesRemovalTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ContainerParticlesRemovalTest.java @@ -21,13 +21,14 @@ import org.digidoc4j.SignatureBuilder; import org.digidoc4j.SignatureProfile; import org.digidoc4j.exceptions.SignatureNotFoundException; +import org.digidoc4j.impl.asic.AsicContainer; import org.digidoc4j.impl.asic.AsicEntry; import org.digidoc4j.impl.asic.AsicParseResult; +import org.digidoc4j.impl.asic.AsicSignature; import org.digidoc4j.impl.asic.asice.AsicEContainer; import org.digidoc4j.impl.asic.asice.AsicESignature; import org.digidoc4j.impl.asic.asice.bdoc.BDocContainer; import org.digidoc4j.impl.asic.asice.bdoc.BDocContainerBuilder; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; import org.digidoc4j.impl.asic.xades.XadesSignatureWrapper; import org.junit.Test; @@ -50,49 +51,49 @@ public class ContainerParticlesRemovalTest extends AbstractTest { @Test public void signatureRemovalFromBDocContainerThroughoutContainerSavingAndOpening_shouldResultWithCompletelyRemovedSignature() { - BDocContainer container = this.createEmptyContainerBy(BDOC); - container.addDataFile(mockDataFile()); + BDocContainer initialContainer = createEmptyContainerBy(BDOC); + initialContainer.addDataFile(mockDataFile()); - Signature signature = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); - assertSame(1, container.getSignatures().size()); - assertTrue(container.getSignatures().contains(signature)); - assertNull(container.getContainerParseResult()); - assertTrue(container.validate().isValid()); + Signature signature = createSignatureBy(initialContainer, SignatureProfile.LT, pkcs12SignatureToken); + assertSame(1, initialContainer.getSignatures().size()); + assertTrue(initialContainer.getSignatures().contains(signature)); + assertNull(initialContainer.getContainerParseResult()); + assertTrue(initialContainer.validate().isValid()); - InputStream containerStream = container.saveAsStream(); + InputStream containerStream = initialContainer.saveAsStream(); - container = (BDocContainer) ContainerBuilder.aContainer(BDOC).fromStream(containerStream).build(); - assertEquals(1, container.getSignatures().size()); - BDocSignature containerSignature = (BDocSignature) container.getSignatures().get(0); + AsicContainer deserializedContainer = (AsicContainer) ContainerBuilder.aContainer(BDOC).fromStream(containerStream).build(); + assertEquals(1, deserializedContainer.getSignatures().size()); + AsicSignature containerSignature = (AsicSignature) deserializedContainer.getSignatures().get(0); assertEquals(containerSignature.getId(), signature.getId()); - containerParseResultContainsSignature(container.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); - ContainerValidationResult validationResult = container.validate(); + containerParseResultContainsSignature(deserializedContainer.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); + ContainerValidationResult validationResult = deserializedContainer.validate(); assertTrue(validationResult.isValid()); containerValidationResultContainsSignature(validationResult, containerSignature); - container.removeSignature(containerSignature); - assertTrue(container.getSignatures().isEmpty()); - containerParseResultDoesNotContainSignature(container.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); - validationResult = container.validate(); + deserializedContainer.removeSignature(containerSignature); + assertTrue(deserializedContainer.getSignatures().isEmpty()); + containerParseResultDoesNotContainSignature(deserializedContainer.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); + validationResult = deserializedContainer.validate(); assertTrue(validationResult.isValid()); containerValidationResultDoesNotContainSignature(validationResult, containerSignature); - containerStream = container.saveAsStream(); + containerStream = deserializedContainer.saveAsStream(); - container = (BDocContainer) ContainerBuilder.aContainer(BDOC).fromStream(containerStream).build(); - assertTrue(container.getSignatures().isEmpty()); - containerParseResultDoesNotContainSignature(container.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); - validationResult = container.validate(); + deserializedContainer = (AsicContainer) ContainerBuilder.aContainer(BDOC).fromStream(containerStream).build(); + assertTrue(deserializedContainer.getSignatures().isEmpty()); + containerParseResultDoesNotContainSignature(deserializedContainer.getContainerParseResult(), containerSignature.getSignatureDocument().getName()); + validationResult = deserializedContainer.validate(); assertTrue(validationResult.isValid()); containerValidationResultDoesNotContainSignature(validationResult, containerSignature); } @Test public void signatureRemovalFromASiCEContainerThroughoutContainerSavingAndOpening_shouldResultWithCompletelyRemovedSignature() { - AsicEContainer container = this.createEmptyContainerBy(ASICE); + AsicEContainer container = createEmptyContainerBy(ASICE); container.addDataFile(mockDataFile()); - Signature signature = this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + Signature signature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); assertSame(1, container.getSignatures().size()); assertTrue(container.getSignatures().contains(signature)); assertNull(container.getContainerParseResult()); @@ -128,10 +129,10 @@ public void signatureRemovalFromASiCEContainerThroughoutContainerSavingAndOpenin @Test public void addAndRemoveSignatureToNewContainerBeforeSaving_resultsWithCompletelyRemovedSignature() { - BDocContainer container = this.createEmptyContainerBy(BDOC); + BDocContainer container = createEmptyContainerBy(BDOC); container.addDataFile(mockDataFile()); - BDocSignature signature = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); + AsicSignature signature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); container.removeSignature(signature); assertTrue(container.getSignatures().isEmpty()); assertNull(container.getContainerParseResult()); @@ -159,11 +160,11 @@ public void addAndRemoveSignatureToAlreadySignedContainerBeforeSaving_resultsWit @Test public void tryingToRemoveNonExistingSignatureFromBDocContainer_shouldThrowAnException() { - BDocContainer container = this.createEmptyContainerBy(BDOC); + BDocContainer container = createEmptyContainerBy(BDOC); container.addDataFile(mockDataFile()); - Signature containerSignature = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); - Signature unrelatedSignature = this.createSignatureBy(BDOC, SignatureProfile.LT_TM, pkcs12SignatureToken); + Signature containerSignature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + Signature unrelatedSignature = createSignatureBy(BDOC, SignatureProfile.LT, pkcs12SignatureToken); assertEquals(1, container.getSignatures().size()); assertTrue(container.getSignatures().contains(containerSignature)); @@ -180,11 +181,11 @@ public void tryingToRemoveNonExistingSignatureFromBDocContainer_shouldThrowAnExc @Test public void tryingToRemoveNonExistingSignatureFromASiCEContainer_shouldThrowAnException() { - AsicEContainer container = this.createEmptyContainerBy(ASICE); + AsicEContainer container = createEmptyContainerBy(ASICE); container.addDataFile(mockDataFile()); - Signature containerSignature = this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); - Signature unrelatedSignature = this.createSignatureBy(ASICE, SignatureProfile.LT, pkcs12SignatureToken); + Signature containerSignature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + Signature unrelatedSignature = createSignatureBy(ASICE, SignatureProfile.LT, pkcs12SignatureToken); assertEquals(1, container.getSignatures().size()); assertTrue(container.getSignatures().contains(containerSignature)); @@ -201,12 +202,12 @@ public void tryingToRemoveNonExistingSignatureFromASiCEContainer_shouldThrowAnEx @Test public void tryingToRemoveNonExistingSignatureByIndexFromBDocContainer_shouldThrowAnException() { - BDocContainer container = this.createEmptyContainerBy(BDOC); + BDocContainer container = createEmptyContainerBy(BDOC); container.addDataFile(mockDataFile()); - Signature signature = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); + Signature signature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); Signature nonExistingSignature = SignatureBuilder.aSignature(container) - .withSignatureProfile(SignatureProfile.LT_TM) + .withSignatureProfile(SignatureProfile.LT) .withSignatureToken(pkcs12SignatureToken) .withSignatureId("id-non-existing") .invokeSigning(); @@ -226,10 +227,10 @@ public void tryingToRemoveNonExistingSignatureByIndexFromBDocContainer_shouldThr @Test public void tryingToRemoveNonExistingSignatureByIndexFromASiCEContainer_shouldThrowAnException() { - AsicEContainer container = this.createEmptyContainerBy(ASICE); + AsicEContainer container = createEmptyContainerBy(ASICE); container.addDataFile(mockDataFile()); - Signature signature = this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + Signature signature = createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); Signature nonExistingSignature = SignatureBuilder.aSignature(container) .withSignatureProfile(SignatureProfile.LT) .withSignatureToken(pkcs12SignatureToken) @@ -253,7 +254,7 @@ public void tryingToRemoveNonExistingSignatureByIndexFromASiCEContainer_shouldTh public void dataFileRemovalFromBDocContainerThroughoutContainerSavingAndOpening_shouldResultWithCompletelyRemovedData() { DataFile dataFile = mockDataFile(); - BDocContainer container = this.createEmptyContainerBy(BDOC); + BDocContainer container = createEmptyContainerBy(BDOC); container.addDataFile(dataFile); assertTrue(container.getDataFiles().contains(dataFile)); assertNull(container.getContainerParseResult()); @@ -283,7 +284,7 @@ public void dataFileRemovalFromBDocContainerThroughoutContainerSavingAndOpening_ public void dataFileRemovalFromASiCEContainerThroughoutContainerSavingAndOpening_shouldResultWithCompletelyRemovedData() { DataFile dataFile = mockDataFile(); - AsicEContainer container = this.createEmptyContainerBy(ASICE); + AsicEContainer container = createEmptyContainerBy(ASICE); container.addDataFile(dataFile); assertTrue(container.getDataFiles().contains(dataFile)); assertNull(container.getContainerParseResult()); diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/EmptyDataFilesBdocSignatureFinalizerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/EmptyDataFilesBdocSignatureFinalizerTest.java deleted file mode 100644 index eabbf0b19..000000000 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/EmptyDataFilesBdocSignatureFinalizerTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.digidoc4j.impl.bdoc; - -import org.digidoc4j.DataFile; -import org.digidoc4j.SignatureParameters; -import org.digidoc4j.impl.EmptyDataFilesSignatureFinalizerTest; -import org.digidoc4j.impl.SignatureFinalizer; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignatureFinalizer; - -import java.util.List; - -public class EmptyDataFilesBdocSignatureFinalizerTest extends EmptyDataFilesSignatureFinalizerTest { - - @Override - protected SignatureFinalizer createSignatureFinalizerWithDataFiles(List dataFiles) { - return new BDocSignatureFinalizer(dataFiles, new SignatureParameters(), configuration); - } - -} diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ExtendingBDocContainerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ExtendingBDocContainerTest.java index 2d5a4265c..1e1315e7c 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ExtendingBDocContainerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/ExtendingBDocContainerTest.java @@ -1,162 +1,247 @@ /* DigiDoc4J library -* -* This software is released under either the GNU Library General Public -* License (see LICENSE.LGPL). -* -* Note that the only valid version of the LGPL license as far as this -* project is concerned is the original GNU Library General Public License -* Version 2.1, February 1999 -*/ + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ package org.digidoc4j.impl.bdoc; -import static java.lang.Thread.sleep; - import org.digidoc4j.AbstractTest; +import org.digidoc4j.Configuration; import org.digidoc4j.Container; +import org.digidoc4j.ContainerOpener; import org.digidoc4j.Signature; import org.digidoc4j.SignatureProfile; -import org.digidoc4j.exceptions.DigiDoc4JException; import org.digidoc4j.exceptions.NotSupportedException; import org.digidoc4j.test.TestAssert; import org.digidoc4j.test.util.TestDataBuilderUtil; import org.junit.Assert; import org.junit.Test; +import static java.lang.Thread.sleep; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; + public class ExtendingBDocContainerTest extends AbstractTest { + private static final String B_EPES_CONTAINER_PATH = "src/test/resources/testFiles/valid-containers/bdoc-with-b-epes-signature.bdoc"; + private static final String LT_TM_CONTAINER_PATH = "src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc"; + private String containerLocation; @Test - public void extendFromB_BESToTS() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); + public void extendFromB_BESToLT() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + container.saveAsFile(containerLocation); + Assert.assertEquals(1, container.getSignatures().size()); Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); + + container = TestDataBuilderUtil.open(containerLocation); container.extendSignatureProfile(SignatureProfile.LT); - container.saveAsFile(this.getFileBy("bdoc")); + container.saveAsFile(getFileBy("bdoc")); + Assert.assertEquals(1, container.getSignatures().size()); Signature signature = container.getSignatures().get(0); + Assert.assertNotNull(signature.getOCSPCertificate()); Assert.assertEquals(SignatureProfile.LT, signature.getProfile()); Assert.assertTrue(container.validate().isValid()); } @Test - public void extendFromEpesToLT_TM() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_EPES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); - Assert.assertEquals(1, container.getSignatures().size()); - Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); - container.extendSignatureProfile(SignatureProfile.LT_TM); - container.saveAsFile(this.getFileBy("bdoc")); - Assert.assertEquals(1, container.getSignatures().size()); - Signature signature = container.getSignatures().get(0); - Assert.assertNotNull(signature.getOCSPCertificate()); - Assert.assertEquals(SignatureProfile.LT_TM, signature.getProfile()); - Assert.assertTrue(container.validate().isValid()); - } + public void extendFromB_BESToLTA() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + container.saveAsFile(containerLocation); - @Test - public void extendFromB_BESToLTA() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); Assert.assertEquals(1, container.getSignatures().size()); Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); + + container = TestDataBuilderUtil.open(containerLocation); container.extendSignatureProfile(SignatureProfile.LTA); - container.saveAsFile(this.getFileBy("bdoc")); + container.saveAsFile(getFileBy("bdoc")); + Assert.assertEquals(1, container.getSignatures().size()); Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); } - @Test(expected = NotSupportedException.class) - public void extendFromB_BESToLT_TMThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LT_TM); + @Test + public void extendFromB_BESToLT_TM_ThrowsException() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend B_BES signature to LT_TM" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromEpesToLTThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_EPES, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LT); + @Test + public void extendFromB_EPESToLT_TM_ThrowsException() { + Container container = ContainerOpener.open(B_EPES_CONTAINER_PATH, Configuration.of(Configuration.Mode.TEST)); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend B_EPES signature to LT_TM" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromEpesToLTAThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_EPES, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LTA); + @Test + public void extendFromB_EPESToLT_ThrowsException() { + Container container = ContainerOpener.open(B_EPES_CONTAINER_PATH, Configuration.of(Configuration.Mode.TEST)); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend B_EPES signature to LT" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromLTToLT_TMThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LT, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LT_TM); + @Test + public void extendFromB_EPESToLTA_ThrowsException() { + Container container = ContainerOpener.open(B_EPES_CONTAINER_PATH, Configuration.of(Configuration.Mode.TEST)); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LTA) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend B_EPES signature to LTA" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromLTAToLT_TMThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LTA, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LT_TM); + @Test + public void extendFromLTToLT_TM_ThrowsException() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LT signature to LT_TM" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromLTToBESThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LT, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.B_BES); + @Test + public void extendFromLTAToLT_TM_ThrowsException() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT_TM) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LTA signature to LT_TM" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromLTToEPESThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LT, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.B_EPES); + @Test + public void extendFromLTToB_BES_ThrowsException() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.B_BES) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LT signature to B_BES" + )); } - @Test(expected = NotSupportedException.class) - public void extendFromLT_TMToLTThrowsException() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LT_TM, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LT); + @Test + public void extendFromLTToB_EPES_ThrowsException() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.B_EPES) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LT signature to B_EPES" + )); } - @Test(expected = DigiDoc4JException.class) - public void extendToWhenConfirmationAlreadyExists() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); - Assert.assertEquals(1, container.getSignatures().size()); - Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); - container.extendSignatureProfile(SignatureProfile.LT); - container.extendSignatureProfile(SignatureProfile.LT); + @Test + public void extendFromLT_TMToLT_ThrowsException() { + Container container = ContainerOpener.open(LT_TM_CONTAINER_PATH, Configuration.of(Configuration.Mode.TEST)); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LT) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LT_TM signature to LT" + )); + } + + @Test + public void extendToWhenConfirmationAlreadyExists() { + Container initialContainer = createNonEmptyContainer(); + createSignatureBy(initialContainer, SignatureProfile.B_BES, pkcs12SignatureToken); + initialContainer.saveAsFile(containerLocation); + + Assert.assertEquals(1, initialContainer.getSignatures().size()); + Assert.assertNull(initialContainer.getSignatures().get(0).getOCSPCertificate()); + + Container deserializedContainer = TestDataBuilderUtil.open(containerLocation); + deserializedContainer.extendSignatureProfile(SignatureProfile.LT); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> deserializedContainer.extendSignatureProfile(SignatureProfile.LT) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LT signature to LT" + )); } @Test - public void extendToWithMultipleSignatures() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); + public void extendToWithMultipleSignatures() { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + container.saveAsFile(containerLocation); + Assert.assertEquals(2, container.getSignatures().size()); Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); Assert.assertNull(container.getSignatures().get(1).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); + + container = TestDataBuilderUtil.open(containerLocation); container.extendSignatureProfile(SignatureProfile.LT); - String containerPath = this.getFileBy("bdoc"); + String containerPath = getFileBy("bdoc"); container.saveAsFile(containerPath); + container = TestDataBuilderUtil.open(containerPath); + Assert.assertEquals(2, container.getSignatures().size()); Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); Assert.assertNotNull(container.getSignatures().get(1).getOCSPCertificate()); @@ -164,19 +249,22 @@ public void extendToWithMultipleSignatures() throws Exception { } @Test - public void extendToWithMultipleSignaturesAndMultipleFiles() throws Exception { - Container container = this.createNonEmptyContainer(); + public void extendToWithMultipleSignaturesAndMultipleFiles() { + Container container = createNonEmptyContainer(); container.addDataFile("src/test/resources/testFiles/helper-files/test.xml", "text/xml"); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - this.createSignatureBy(container, SignatureProfile.B_BES, this.pkcs12SignatureToken); - container.saveAsFile(this.containerLocation); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + container.saveAsFile(containerLocation); + Assert.assertEquals(2, container.getSignatures().size()); Assert.assertEquals(2, container.getDataFiles().size()); Assert.assertNull(container.getSignatures().get(0).getOCSPCertificate()); Assert.assertNull(container.getSignatures().get(1).getOCSPCertificate()); - container = TestDataBuilderUtil.open(this.containerLocation); + + container = TestDataBuilderUtil.open(containerLocation); container.extendSignatureProfile(SignatureProfile.LT); - container.saveAsFile(this.getFileBy("bdoc")); + container.saveAsFile(getFileBy("bdoc")); + Assert.assertEquals(2, container.getSignatures().size()); Assert.assertEquals(2, container.getDataFiles().size()); Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); @@ -185,21 +273,31 @@ public void extendToWithMultipleSignaturesAndMultipleFiles() throws Exception { } @Test - public void testContainerExtensionFromLTtoLTA() throws Exception { - Container container = this.createNonEmptyContainer(); - this.createSignatureBy(container, SignatureProfile.LT, this.pkcs12SignatureToken); + public void testContainerExtensionFromLTtoLTA() throws InterruptedException { + Container container = createNonEmptyContainer(); + createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); sleep(1100); + container.extendSignatureProfile(SignatureProfile.LTA); + Assert.assertNotNull(container.getSignatures().get(0).getOCSPCertificate()); TestAssert.assertContainerIsValid(container); } - @Test(expected = NotSupportedException.class) - public void extensionNotPossibleWhenSignatureLevelIsSame() throws Exception { - Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); + @Test + public void extensionNotPossibleWhenSignatureLevelIsSame() { + Container container = createNonEmptyContainer(); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); - this.createSignatureBy(container, SignatureProfile.LTA, this.pkcs12SignatureToken); - container.extendSignatureProfile(SignatureProfile.LTA); + createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken); + + NotSupportedException caughtException = assertThrows( + NotSupportedException.class, + () -> container.extendSignatureProfile(SignatureProfile.LTA) + ); + + assertThat(caughtException.getMessage(), containsString( + "It is not possible to extend LTA signature to LTA" + )); } /* @@ -208,7 +306,7 @@ public void extensionNotPossibleWhenSignatureLevelIsSame() throws Exception { @Override protected void before() { - this.containerLocation = this.getFileBy("bdoc"); + containerLocation = getFileBy("bdoc"); } } \ No newline at end of file diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java index 56ff13155..42ced0ca8 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java @@ -40,6 +40,11 @@ import java.nio.file.Paths; import java.security.cert.X509Certificate; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.matchesRegex; +import static org.hamcrest.Matchers.startsWith; + /** * Description of tests by their suffix: *

@@ -58,209 +63,226 @@ */ public class IncompleteSigningTest extends AbstractTest { - private static final String VALIDATION_ERROR_MESSAGE = "The certificate validation is not conclusive!"; - - @Test(expected = OCSPRequestFailedException.class) - public void signatureProfileLtTmShouldFailWhenSigningCertificateIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); - } + private static final String CERTIFICATE_VALIDATION_EXCEPTION_MESSAGE_REGEX = "OCSP response certificate match is not found in TSL"; + private static final String CONTAINER_VALIDATION_ERROR_MESSAGE = "The certificate validation is not conclusive!"; + private static final String OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART = "OCSP request failed"; + private static final String TECHNICAL_EXCEPTION_TSP_MESSAGE_PART = "Got error in signing process: Failed to POST URL: http://demo.sk.ee/tsa"; + private static final String TSL_REFRESH_EXCEPTION_MESSAGE_PART = "Failed to download LoTL"; - @Test(expected = OCSPRequestFailedException.class) + @Test public void signatureProfileLtShouldFailWhenSigningCertificateIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + OCSPRequestFailedException caughtException = assertThrows( + OCSPRequestFailedException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } - @Test(expected = OCSPRequestFailedException.class) + @Test public void signatureProfileLtaShouldFailWhenSigningCertificateIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + OCSPRequestFailedException caughtException = assertThrows( + OCSPRequestFailedException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } @Test public void signatureProfileBbesShouldNotFailWhenSigningCertificateIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_BES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Container container = createNonEmptyContainerByConfiguration(); - @Test - public void signatureProfileBepesShouldNotFailWhenSigningCertificateIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_EPES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - @Test(expected = CertificateValidationException.class) - public void signatureProfileLtTmShouldFailWhenOcspResponderIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); + ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); + TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } - @Test(expected = CertificateValidationException.class) + @Test public void signatureProfileLtShouldFailWhenOcspResponderIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + CertificateValidationException caughtException = assertThrows( + CertificateValidationException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), matchesRegex(CERTIFICATE_VALIDATION_EXCEPTION_MESSAGE_REGEX)); } - @Test(expected = CertificateValidationException.class) + @Test public void signatureProfileLtaShouldFailWhenOcspResponderIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + CertificateValidationException caughtException = assertThrows( + CertificateValidationException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), matchesRegex(CERTIFICATE_VALIDATION_EXCEPTION_MESSAGE_REGEX)); } @Test public void signatureProfileBbesShouldNotFailWhenOcspResponderIsNotTrustedByTSL() { setUpProdConfigurationWithTestTsaAndOcsp(); ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_BES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Container container = createNonEmptyContainerByConfiguration(); + + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - @Test - public void signatureProfileBepesShouldNotFailWheOcspResponderIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_EPES, pkcs12SignatureToken); ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); + TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } - @Test(expected = TslRefreshException.class) - public void signatureProfileLtTmShouldFailWhenTslCouldNotBeLoadedWithDefaultTslCallback() { + @Test + public void signatureProfileLtShouldFailWhenTslCouldNotBeLoadedWithDefaultTslCallback() { setUpTestConfigurationWithEmptyTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); - } + Container container = createNonEmptyContainerByConfiguration(); - @Test(expected = OCSPRequestFailedException.class) - public void signatureProfileLtTmShouldFailWhenTslCouldNotBeLoadedWithCustomTslCallback() { - setUpTestConfigurationWithEmptyTSL(); - configuration.setTslRefreshCallback(new MockTSLRefreshCallback(true)); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); - } + TslRefreshException caughtException = assertThrows( + TslRefreshException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); - @Test(expected = TslRefreshException.class) - public void signatureProfileLtShouldFailWhenTslCouldNotBeLoadedWithDefaultTslCallback() { - setUpTestConfigurationWithEmptyTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + assertThat(caughtException.getMessage(), startsWith(TSL_REFRESH_EXCEPTION_MESSAGE_PART)); } - @Test(expected = OCSPRequestFailedException.class) + @Test public void signatureProfileLtShouldFailWhenTslCouldNotBeLoadedWithCustomTslCallback() { setUpTestConfigurationWithEmptyTSL(); configuration.setTslRefreshCallback(new MockTSLRefreshCallback(true)); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + OCSPRequestFailedException caughtException = assertThrows( + OCSPRequestFailedException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } - @Test(expected = TslRefreshException.class) + @Test public void signatureProfileLtaShouldFailWhenTslCouldNotBeLoadedWithDefaultTslCallback() { setUpTestConfigurationWithEmptyTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + TslRefreshException caughtException = assertThrows( + TslRefreshException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), startsWith(TSL_REFRESH_EXCEPTION_MESSAGE_PART)); } - @Test(expected = OCSPRequestFailedException.class) + @Test public void signatureProfileLtaShouldFailWhenTslCouldNotBeLoadedWithCustomTslCallback() { setUpTestConfigurationWithEmptyTSL(); configuration.setTslRefreshCallback(new MockTSLRefreshCallback(true)); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + OCSPRequestFailedException caughtException = assertThrows( + OCSPRequestFailedException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } @Test public void signatureProfileBbesShouldNotFailWhenTslCouldNotBeLoaded() { setUpTestConfigurationWithEmptyTSL(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_BES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Container container = createNonEmptyContainerByConfiguration(); + + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - @Test - public void signatureProfileBepesShouldNotFailWhenTslCouldNotBeLoaded() { - setUpTestConfigurationWithOkTslButFailingDataLoaders(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_EPES, pkcs12SignatureToken); ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); + TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } - @Test(expected = TslRefreshException.class) - public void signatureProfileLtTmShouldFailWhenTslLoadingFailsWithDefaultTslCallback() { + @Test + public void signatureProfileLtShouldFailWhenTslLoadingFails() { setUpTestConfigurationWithFailingTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); - } + Container container = createNonEmptyContainerByConfiguration(); - @Test(expected = OCSPRequestFailedException.class) - public void signatureProfileLtTmShouldFailWhenTslLoadingFailsWithCustomTslCallback() { - setUpTestConfigurationWithFailingTSL(); - configuration.setTslRefreshCallback(new MockTSLRefreshCallback(true)); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); - } + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); - @Test(expected = TechnicalException.class) - public void signatureProfileLtShouldFailWhenTslLoadingFails() { - setUpTestConfigurationWithFailingTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + assertThat(caughtException.getMessage(), containsString(TECHNICAL_EXCEPTION_TSP_MESSAGE_PART)); } - @Test(expected = TechnicalException.class) + @Test public void signatureProfileLtaShouldFailWhenTslLoadingFails() { setUpTestConfigurationWithFailingTSL(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(TECHNICAL_EXCEPTION_TSP_MESSAGE_PART)); } @Test public void signatureProfileBbesShouldNotFailWhenTslLoadingFails() { setUpTestConfigurationWithFailingTSL(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_BES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Container container = createNonEmptyContainerByConfiguration(); - @Test - public void signatureProfileBepesShouldNotFailWhenTslLoadingFails() { - setUpTestConfigurationWithFailingTSL(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_EPES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - @Test(expected = TechnicalException.class) - public void signatureProfileLtTmShouldFailWhenDataLoadersFail() { - setUpTestConfigurationWithOkTslButFailingDataLoaders(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT_TM, pkcs12SignatureToken); + ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); + TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } - @Test(expected = TechnicalException.class) + @Test public void signatureProfileLtShouldFailWhenDataLoadersFail() { setUpTestConfigurationWithOkTslButFailingDataLoaders(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LT, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(TECHNICAL_EXCEPTION_TSP_MESSAGE_PART)); } - @Test(expected = TechnicalException.class) + @Test public void signatureProfileLtaShouldFailWhenDataLoadersFail() { setUpTestConfigurationWithOkTslButFailingDataLoaders(); - createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerByConfiguration(); + + TechnicalException caughtException = assertThrows( + TechnicalException.class, + () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + ); + + assertThat(caughtException.getMessage(), containsString(TECHNICAL_EXCEPTION_TSP_MESSAGE_PART)); } @Test public void signatureProfileBbesShouldNotFailWhenDataLoadersFail() { setUpTestConfigurationWithOkTslButFailingDataLoaders(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_BES, pkcs12SignatureToken); - ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); - } + Container container = createNonEmptyContainerByConfiguration(); + + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); - @Test - public void signatureProfileBepesShouldNotFailWhenDataLoadersFail() { - setUpTestConfigurationWithOkTslButFailingDataLoaders(); - Signature signature = createSignatureBy(createNonEmptyContainerByConfiguration(), SignatureProfile.B_EPES, pkcs12SignatureToken); ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), VALIDATION_ERROR_MESSAGE); + TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } /** diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/SignatureTimeTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/SignatureTimeTest.java index 5888d72aa..b12e8b2f5 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/SignatureTimeTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/SignatureTimeTest.java @@ -15,7 +15,6 @@ import org.digidoc4j.Container; import org.digidoc4j.SignatureProfile; import org.digidoc4j.impl.asic.asice.AsicESignature; -import org.digidoc4j.impl.asic.asice.bdoc.BDocSignature; import org.junit.Assert; import org.junit.Test; @@ -30,53 +29,33 @@ public class SignatureTimeTest extends AbstractTest { - @Test - public void signatureProfileLTTMTest() { - Instant notBefore = truncatedCurrentTime(); - Container container = this.createNonEmptyContainer(); - BDocSignature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LT_TM, pkcs12SignatureToken); - container.addSignature(signature); - assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ofMinutes(1L)); - assertTimeBetweenNotBeforeAndNow(signature.getTrustedSigningTime(), notBefore, Duration.ofMinutes(1L)); - } - @Test public void signatureProfileLTTest() { Instant notBefore = truncatedCurrentTime(); - Container container = this.createNonEmptyContainer(); - AsicESignature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LT, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Container.DocumentType.ASICE); + AsicESignature signature = createSignatureBy(Container.DocumentType.ASICE, SignatureProfile.LT, pkcs12SignatureToken); container.addSignature(signature); - assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ofMinutes(1L)); + assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ZERO); assertTimeBetweenNotBeforeAndNow(signature.getTrustedSigningTime(), notBefore, Duration.ofMinutes(1L)); } @Test public void signatureProfileLTATest() { Instant notBefore = truncatedCurrentTime(); - Container container = this.createNonEmptyContainer(); - AsicESignature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.LTA, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Container.DocumentType.ASICE); + AsicESignature signature = createSignatureBy(Container.DocumentType.ASICE, SignatureProfile.LTA, pkcs12SignatureToken); container.addSignature(signature); - assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ofMinutes(1L)); + assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ZERO); assertTimeBetweenNotBeforeAndNow(signature.getTrustedSigningTime(), notBefore, Duration.ofMinutes(1L)); } @Test public void signatureProfileB_BESTest() { Instant notBefore = truncatedCurrentTime(); - Container container = this.createNonEmptyContainer(); - AsicESignature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_BES, pkcs12SignatureToken); - container.addSignature(signature); - assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ofMinutes(1L)); - Assert.assertNull(signature.getTrustedSigningTime()); - } - - @Test - public void signatureProfileB_EPESTest() { - Instant notBefore = truncatedCurrentTime(); - Container container = this.createNonEmptyContainer(); - AsicESignature signature = createSignatureBy(Container.DocumentType.BDOC, SignatureProfile.B_EPES, pkcs12SignatureToken); + Container container = createNonEmptyContainerBy(Container.DocumentType.ASICE); + AsicESignature signature = createSignatureBy(Container.DocumentType.ASICE, SignatureProfile.B_BES, pkcs12SignatureToken); container.addSignature(signature); - assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ofMinutes(1L)); + assertTimeBetweenNotBeforeAndNow(signature.getClaimedSigningTime(), notBefore, Duration.ZERO); Assert.assertNull(signature.getTrustedSigningTime()); } @@ -86,19 +65,20 @@ public void signatureProfileB_EPESTest() { @Override protected void before() { - this.configuration = Configuration.of(Configuration.Mode.TEST); + configuration = Configuration.of(Configuration.Mode.TEST); } private static Instant truncatedCurrentTime() { return Instant.now().truncatedTo(ChronoUnit.SECONDS); } - private static void assertTimeBetweenNotBeforeAndNow(Date time, Instant notBefore, Duration notAfterSkew) { + private static void assertTimeBetweenNotBeforeAndNow(Date time, Instant notBefore, Duration clockSkew) { Instant timeAsInstant = time.toInstant(); + notBefore = notBefore.minus(clockSkew); if (timeAsInstant.isBefore(notBefore)) { Assert.fail(String.format("Time '%s' is before 'not-before' (%s)", timeAsInstant, notBefore)); } - Instant notAfter = Instant.now().plus(notAfterSkew); + Instant notAfter = Instant.now().plus(clockSkew); if (timeAsInstant.isAfter(notAfter)) { Assert.fail(String.format("Time '%s' is after 'not-after' (%s)", timeAsInstant, notAfter)); } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSerializationTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSerializationTest.java index 43a539129..9c3864434 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSerializationTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSerializationTest.java @@ -29,10 +29,10 @@ public void bdocContainerSigningWithSerialization() { Container container = this.createEmptyContainerBy(Container.DocumentType.BDOC); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); assertEquals(0, container.getSignatures().size()); - container = serializeAndAddSignature(container, SignatureProfile.LT_TM); + container = serializeAndAddSignature(container, SignatureProfile.LT); assertTrue(container.validate().isValid()); assertEquals(1, container.getSignatures().size()); - assertTimemarkSignature(container.getSignatures().get(0)); + assertTimestampSignature(container.getSignatures().get(0)); assertBDocContainer(container); } @@ -49,20 +49,22 @@ public void asiceContainerSigningWithSerialization() { } @Test - public void asicsContainerSigningWithSerialization() { - Container container = this.createEmptyContainerBy(Container.DocumentType.ASICS); + public void asiceLtaContainerSigningWithSerialization() { + Container container = this.createEmptyContainerBy(Container.DocumentType.ASICE); container.addDataFile("src/test/resources/testFiles/helper-files/test.txt", "text/plain"); assertEquals(0, container.getSignatures().size()); - container = serializeAndAddSignature(container, SignatureProfile.LT); + container = serializeAndAddSignature(container, SignatureProfile.LTA); assertTrue(container.validate().isValid()); - assertAsicSContainer(container); + assertEquals(1, container.getSignatures().size()); + assertArchiveTimestampSignature(container.getSignatures().get(0)); + assertAsicEContainer(container); } private Container serializeAndAddSignature(Container container, SignatureProfile signatureProfile) { byte[] serializedContainer = SerializationUtils.serialize(container); DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(this.pkcs12SignatureToken.getCertificate()) + .withSigningCertificate(pkcs12SignatureToken.getCertificate()) .withSignatureProfile(signatureProfile) .buildDataToSign(); @@ -73,9 +75,7 @@ private Container serializeAndAddSignature(Container container, SignatureProfile Signature signature = dataToSign.finalize(signatureValue); container = SerializationUtils.deserialize(serializedContainer); - if (!container.getType().equalsIgnoreCase(Container.DocumentType.ASICS.name())) { - container.addSignature(signature); - } + container.addSignature(signature); return container; } } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSignatureFinalizerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSignatureFinalizerTest.java index f72084929..3c8432c6c 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSignatureFinalizerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/AsicSignatureFinalizerTest.java @@ -20,30 +20,12 @@ import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; public class AsicSignatureFinalizerTest extends AbstractTest { - @Test - public void bdocSignatureFinalization() { - Container container = createEmptyContainerBy(Container.DocumentType.BDOC); - container.addDataFile(new ByteArrayInputStream("something".getBytes(StandardCharsets.UTF_8)), "file name", "text/plain"); - - DataToSign dataToSign = SignatureBuilder.aSignature(container) - .withSigningCertificate(pkcs12SignatureToken.getCertificate()) - .withSignatureProfile(SignatureProfile.LT_TM) - .buildDataToSign(); - - byte[] signatureDigest = sign(dataToSign.getDataToSign(), dataToSign.getDigestAlgorithm()); - - SignatureFinalizer signatureFinalizer = SignatureFinalizerBuilder.aFinalizer(container, dataToSign.getSignatureParameters()); - Signature signature = signatureFinalizer.finalizeSignature(signatureDigest); - assertTimemarkSignature(signature); - assertValidSignature(signature); - } - @Test public void asicESignatureFinalization() { Container container = createEmptyContainerBy(Container.DocumentType.ASICE); diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicESignatureFinalizerTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicESignatureFinalizerTest.java index 4848799c8..f1ec0ccf3 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicESignatureFinalizerTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/asic/EmptyDataFilesAsicESignatureFinalizerTest.java @@ -1,3 +1,13 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.impl.bdoc.asic; import org.digidoc4j.DataFile; diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/report/ValidationReportTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/report/ValidationReportTest.java index 951c41dfb..755b93b3f 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/report/ValidationReportTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/report/ValidationReportTest.java @@ -10,20 +10,18 @@ package org.digidoc4j.impl.bdoc.report; -import java.nio.file.Paths; - import org.digidoc4j.AbstractTest; import org.digidoc4j.Configuration; import org.digidoc4j.Container; -import org.digidoc4j.SignatureValidationResult; import org.digidoc4j.Signature; import org.digidoc4j.SignatureProfile; +import org.digidoc4j.SignatureValidationResult; import org.digidoc4j.test.TestAssert; import org.digidoc4j.test.util.TestDataBuilderUtil; import org.junit.Assert; import org.junit.Test; -import eu.europa.esig.dss.model.MimeType; +import java.nio.file.Paths; public class ValidationReportTest extends AbstractTest { @@ -55,9 +53,7 @@ public void validContainerWithOneSignature() throws Exception { @Test public void validContainerWithOneTmSignature() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); - container.addDataFile("src/test/resources/testFiles/special-char-files/dds_acrobat.pdf", MimeType.PDF.getMimeTypeString()); - this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); + Container container = TestDataBuilderUtil.open(BDOC_WITH_TM_SIG); String report = container.validate().getReport(); TestAssert.assertXPathHasValue("1", "/SimpleReport/SignaturesCount", report); TestAssert.assertXPathHasValue("1", "/SimpleReport/ValidSignaturesCount", report); @@ -65,9 +61,8 @@ public void validContainerWithOneTmSignature() throws Exception { TestAssert.assertXPathHasValue("XAdES-BASELINE-LT-TM", "/SimpleReport/Signature/@SignatureFormat", report); TestAssert.assertXPathHasValue("TOTAL_PASSED", "/SimpleReport/Signature/Indication", report); TestAssert.assertXPathHasValue("test.txt", "/SimpleReport/Signature/SignatureScope[1]/@name", report); - TestAssert.assertXPathHasValue("dds_acrobat.pdf", "/SimpleReport/Signature/SignatureScope[2]/@name", report); TestAssert.assertXPathHasValue("true", "count(/SimpleReport/Signature/CertificateChain/Certificate) > 1", report); - TestAssert.assertXPathHasValue("O’CONNEŽ-ŠUSLIK TESTNUMBER,MARY ÄNN,60001013739", "/SimpleReport/Signature/CertificateChain/Certificate[1]/qualifiedName", report); + TestAssert.assertXPathHasValue("ŽÕRINÜWŠKY,MÄRÜ-LÖÖZ,11404176865", "/SimpleReport/Signature/CertificateChain/Certificate[1]/qualifiedName", report); TestAssert.assertXPathHasValue("1", "count(/SimpleReport/Signature/SigningTime)", report); TestAssert.assertXPathHasValue("1", "count(/SimpleReport/Signature/BestSignatureTime)", report); } @@ -90,8 +85,7 @@ public void containerWithOneBesSignature() throws Exception { @Test public void containerWithOneEpesSignature() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); - this.createSignatureBy(container, SignatureProfile.B_EPES, pkcs12SignatureToken); + Container container = TestDataBuilderUtil.open(BDOC_WITH_B_EPES_SIG); String report = container.validate().getReport(); TestAssert.assertXPathHasValue("1", "/SimpleReport/SignaturesCount", report); TestAssert.assertXPathHasValue("0", "/SimpleReport/ValidSignaturesCount", report); @@ -99,32 +93,30 @@ public void containerWithOneEpesSignature() throws Exception { TestAssert.assertXPathHasValue("XAdES-BASELINE-B-EPES", "/SimpleReport/Signature/@SignatureFormat", report); TestAssert.assertXPathHasValue("INDETERMINATE", "/SimpleReport/Signature/Indication", report); TestAssert.assertXPathHasValue("TRY_LATER", "/SimpleReport/Signature/SubIndication", report); - TestAssert.assertXPathHasValue("test.txt", "/SimpleReport/Signature/SignatureScope/@name", report); + TestAssert.assertXPathHasValue("junit4090904941259216539.tmp", "/SimpleReport/Signature/SignatureScope/@name", report); TestAssert.assertXPathHasValue("true", "count(/SimpleReport/Signature/CertificateChain/Certificate) > 1", report); - TestAssert.assertXPathHasValue("O’CONNEŽ-ŠUSLIK TESTNUMBER,MARY ÄNN,60001013739", "/SimpleReport/Signature/CertificateChain/Certificate[1]/qualifiedName", report); + TestAssert.assertXPathHasValue("ŽÕRINÜWŠKY,MÄRÜ-LÖÖZ,11404176865", "/SimpleReport/Signature/CertificateChain/Certificate[1]/qualifiedName", report); } @Test public void validContainerWithTwoSignatures() throws Exception { - Container container = this.createNonEmptyContainerBy(Paths.get("src/test/resources/testFiles/helper-files/test.txt")); - Signature signature1 = this.createSignatureBy(container, SignatureProfile.LT_TM, pkcs12SignatureToken); - Signature signature2 = this.createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken); + Container container = TestDataBuilderUtil.open(BDOC_WITH_TM_AND_TS_SIG); SignatureValidationResult result = container.validate(); Assert.assertTrue(result.isValid()); String report = result.getReport(); TestAssert.assertXPathHasValue("2", "/SimpleReport/SignaturesCount", report); TestAssert.assertXPathHasValue("2", "/SimpleReport/ValidSignaturesCount", report); TestAssert.assertXPathHasValue("2", "count(/SimpleReport/Signature)", report); - TestAssert.assertXPathHasValue(signature1.getId(), "/SimpleReport/Signature[1]/@Id", report); - TestAssert.assertXPathHasValue(signature2.getId(), "/SimpleReport/Signature[2]/@Id", report); + TestAssert.assertXPathHasValue("id-6a5d6671af7a9e0ab9a5e4d49d69800d", "/SimpleReport/Signature[1]/@Id", report); + TestAssert.assertXPathHasValue("id-df8be709dc86f84f4eb34d4ed3a946c4", "/SimpleReport/Signature[2]/@Id", report); TestAssert.assertXPathHasValue("XAdES-BASELINE-LT-TM", "/SimpleReport/Signature[1]/@SignatureFormat", report); TestAssert.assertXPathHasValue("XAdES-BASELINE-LT", "/SimpleReport/Signature[2]/@SignatureFormat", report); TestAssert.assertXPathHasValue("test.txt", "/SimpleReport/Signature[1]/SignatureScope/@name", report); TestAssert.assertXPathHasValue("test.txt", "/SimpleReport/Signature[2]/SignatureScope/@name", report); TestAssert.assertXPathHasValue("true", "count(/SimpleReport/Signature[1]/CertificateChain/Certificate) > 1", report); - TestAssert.assertXPathHasValue("O’CONNEŽ-ŠUSLIK TESTNUMBER,MARY ÄNN,60001013739", "/SimpleReport/Signature[1]/CertificateChain/Certificate[1]/qualifiedName", report); + TestAssert.assertXPathHasValue("ŽÕRINÜWŠKY,MÄRÜ-LÖÖZ,11404176865", "/SimpleReport/Signature[1]/CertificateChain/Certificate[1]/qualifiedName", report); TestAssert.assertXPathHasValue("true", "count(/SimpleReport/Signature[2]/CertificateChain/Certificate) > 1", report); - TestAssert.assertXPathHasValue("O’CONNEŽ-ŠUSLIK TESTNUMBER,MARY ÄNN,60001013739", "/SimpleReport/Signature[2]/CertificateChain/Certificate[1]/qualifiedName", report); + TestAssert.assertXPathHasValue("ŽÕRINÜWŠKY,MÄRÜ-LÖÖZ,11404176865", "/SimpleReport/Signature[2]/CertificateChain/Certificate[1]/qualifiedName", report); } @Test From a175144eacdfa530e10784c8348aa5d634daf3e0 Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Tue, 11 Jul 2023 15:30:22 +0300 Subject: [PATCH 08/21] DD4J-881 Use org.glassfish.jaxb:jaxb-core instead of com.sun.xml.bind:jaxb-core dependency --- digidoc4j/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digidoc4j/pom.xml b/digidoc4j/pom.xml index 4cd4c40bb..a634f1a1a 100644 --- a/digidoc4j/pom.xml +++ b/digidoc4j/pom.xml @@ -242,7 +242,7 @@ 2.3.8 - com.sun.xml.bind + org.glassfish.jaxb jaxb-core 2.3.0.1 From 4b84d39b4d21912cd01e30b39d0698aee4ec9194 Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Tue, 11 Jul 2023 16:15:09 +0300 Subject: [PATCH 09/21] Update version number to 5.2.0-SNAPSHOT --- ddoc4j/pom.xml | 4 ++-- digidoc4j/pom.xml | 6 +++--- digidoc4j/src/main/java/org/digidoc4j/Version.java | 2 +- pom.xml | 2 +- publish.sh | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ddoc4j/pom.xml b/ddoc4j/pom.xml index e1bfbc7de..501f3f94f 100644 --- a/ddoc4j/pom.xml +++ b/ddoc4j/pom.xml @@ -5,7 +5,7 @@ ddoc4j jar - 5.1.0 + 5.2.0-SNAPSHOT DDoc4J DDoc4J is Java Library for validating DDOC documents. It's not recommended to use it directly but rather through DigiDoc4J's API. @@ -14,7 +14,7 @@ digidoc4j-parent org.digidoc4j - 5.1.0 + 5.2.0-SNAPSHOT diff --git a/digidoc4j/pom.xml b/digidoc4j/pom.xml index a634f1a1a..38e12d96a 100644 --- a/digidoc4j/pom.xml +++ b/digidoc4j/pom.xml @@ -6,7 +6,7 @@ digidoc4j jar - 5.1.0 + 5.2.0-SNAPSHOT DigiDoc4j DigiDoc4j is a Java library for digitally signing documents and creating digital signature containers @@ -17,7 +17,7 @@ digidoc4j-parent org.digidoc4j - 5.1.0 + 5.2.0-SNAPSHOT @@ -44,7 +44,7 @@ ddoc4j org.digidoc4j - 5.1.0 + 5.2.0-SNAPSHOT diff --git a/digidoc4j/src/main/java/org/digidoc4j/Version.java b/digidoc4j/src/main/java/org/digidoc4j/Version.java index aa96f2d21..ac3bf126f 100644 --- a/digidoc4j/src/main/java/org/digidoc4j/Version.java +++ b/digidoc4j/src/main/java/org/digidoc4j/Version.java @@ -11,5 +11,5 @@ package org.digidoc4j; public class Version { - public static final String VERSION = "5.1.0"; + public static final String VERSION = "5.2.0-SNAPSHOT"; } diff --git a/pom.xml b/pom.xml index a216d6a1b..159605abb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.digidoc4j digidoc4j-parent - 5.1.0 + 5.2.0-SNAPSHOT pom DigiDoc4J parent diff --git a/publish.sh b/publish.sh index f0f26ecb6..781ea5891 100755 --- a/publish.sh +++ b/publish.sh @@ -1,6 +1,6 @@ #!/bin/bash -version="5.1.0" +version="5.2.0-SNAPSHOT" staging_url="https://oss.sonatype.org/service/local/staging/deploy/maven2/" repositoryId="ossrh" From ecebf399eb59f4345e8677a2fdf31d26789fd875 Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Mon, 7 Aug 2023 15:40:58 +0300 Subject: [PATCH 10/21] DD4J-897 Remove time-mark signature creation test from performance tests --- .../test/java/org/digidoc4j/PerformanceTest.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/digidoc4j/src/test/java/org/digidoc4j/PerformanceTest.java b/digidoc4j/src/test/java/org/digidoc4j/PerformanceTest.java index 3bebab866..d838e2c90 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/PerformanceTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/PerformanceTest.java @@ -200,24 +200,17 @@ public void saveExistingContainerOnDisk() { @Test @PerfTest(invocations = 10) - public void loadingTSL() throws Exception { + public void loadingTSL() { TSLCertificateSource tsl = new Configuration(Configuration.Mode.PROD).getTSL(); tsl.invalidateCache(); tsl.refresh(); } - @Test - @PerfTest(invocations = 50) - public void createBDocTmSignature() { - Container container = this.openContainerByConfiguration(Paths.get("src/test/resources/testFiles/valid-containers/valid-bdoc-tm.bdoc")); - this.createSignatureBy(container, SignatureProfile.LT_TM, DigestAlgorithm.SHA256, this.pkcs12SignatureToken); - } - @Test @PerfTest(invocations = 50) public void createAsicSignature() { Container container = this.openContainerByConfiguration(Paths.get("src/test/resources/testFiles/valid-containers/valid-asice.asice")); - this.createSignatureBy(container, SignatureProfile.LT, DigestAlgorithm.SHA256, this.pkcs12SignatureToken); + this.createSignatureBy(container, SignatureProfile.LT, DigestAlgorithm.SHA256, pkcs12SignatureToken); } /* @@ -227,8 +220,7 @@ public void createAsicSignature() { @Override protected void before() { this.configuration = Configuration.of(Configuration.Mode.TEST); - //this.configuration.getTSL().refresh(); - this.configManagerInitializer.initConfigManager(this.configuration); + configManagerInitializer.initConfigManager(this.configuration); } } From 2730887927af713ddfff8a2638f9eb70774768ea Mon Sep 17 00:00:00 2001 From: Risto Seene Date: Wed, 9 Aug 2023 13:16:51 +0300 Subject: [PATCH 11/21] DD4J-901 Fix unit tests broken by changes in SK demo OCSP responders --- .../test/java/org/digidoc4j/AiaOcspTest.java | 10 +- .../java/org/digidoc4j/SignatureTest.java | 17 +- .../digidoc4j/impl/CommonOCSPSourceTest.java | 23 +-- .../impl/bdoc/IncompleteSigningTest.java | 194 +++++++++++++----- .../digidoc4j/test/TestSignatureToken.java | 72 +++++++ .../test/util/TestCertificateUtil.java | 20 ++ .../org/digidoc4j/test/util/TestOcspUtil.java | 28 +++ .../valid-containers/valid-bdoc-tm-newer.bdoc | Bin 0 -> 7199 bytes 8 files changed, 292 insertions(+), 72 deletions(-) create mode 100644 digidoc4j/src/test/java/org/digidoc4j/test/TestSignatureToken.java create mode 100644 digidoc4j/src/test/resources/testFiles/valid-containers/valid-bdoc-tm-newer.bdoc diff --git a/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java b/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java index 2859b4445..d6e651994 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/AiaOcspTest.java @@ -5,6 +5,9 @@ import java.io.File; +import static org.digidoc4j.test.TestAssert.assertContainerIsValid; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesRegex; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -22,8 +25,11 @@ public void signAsiceContainerWithoutAiaOcsp() { .withConfiguration(configuration) .build(); this.createSignatureBy(container, pkcs12SignatureToken); - assertTrue(container.validate().isValid()); - assertEquals("EMAILADDRESS=pki@sk.ee, CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE", container.getSignatures().get(0).getOCSPCertificate().getSubjectName()); + assertContainerIsValid(container); + assertThat( + container.getSignatures().get(0).getOCSPCertificate().getSubjectName(X509Cert.SubjectName.CN), + matchesRegex("TEST of ESTEID-SK 2015 AIA OCSP RESPONDER 202[3-9][0-1][0-9]") + ); } @Test diff --git a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java index 3b3cde689..f30809aca 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/SignatureTest.java @@ -43,6 +43,9 @@ import java.util.Date; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesRegex; + public class SignatureTest extends AbstractTest { @Test @@ -159,12 +162,22 @@ public void testGetOCSPCertificateForDDoc() throws CertificateEncodingException } @Test - public void testGetOCSPCertificateForBDoc() throws CertificateEncodingException { - Signature signature = createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); + public void testGetOCSPCertificateForExistingBDoc() throws CertificateEncodingException { + Container container = ContainerOpener.open("src/test/resources/testFiles/valid-containers/valid-bdoc-tm-newer.bdoc"); + Signature signature = container.getSignatures().get(0); byte[] encoded = signature.getOCSPCertificate().getX509Certificate().getEncoded(); Assert.assertEquals(Certificates.OCSP_CERTIFICATE_2020, Base64.encodeBase64String(encoded)); } + @Test + public void testGetOCSPCertificateForNewBDoc() { + Signature signature = createSignatureBy(Container.DocumentType.BDOC, pkcs12SignatureToken); + assertThat( + signature.getOCSPCertificate().getSubjectName(X509Cert.SubjectName.CN), + matchesRegex("TEST of ESTEID-SK 2015 AIA OCSP RESPONDER 202[3-9][0-1][0-9]") + ); + } + @Test public void testGetProducedAtForDDoc() { configuration = Configuration.of(Configuration.Mode.TEST); diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java index 2f592b46b..fe18b3a1c 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/CommonOCSPSourceTest.java @@ -20,7 +20,6 @@ import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; import org.bouncycastle.cert.ocsp.OCSPReq; -import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cert.ocsp.Req; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; @@ -468,7 +467,7 @@ private void verifyDataLoaderPostInteraction(String requestUrl, boolean preferAi Mockito.verifyNoMoreInteractions(ocspDataLoader); byte[] postContent = postContentCaptor.getValue(); - OCSPReq ocspReq = parseOcspRequest(postContent); + OCSPReq ocspReq = TestOcspUtil.parseOcspRequest(postContent); Extension ocspNonceExtension = ocspReq.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); if (useNonce) { @@ -606,7 +605,7 @@ private static byte[] createOcspResponse( Pair ocspSignerKeyAndCertificateChain, X509CertificateHolder... certificatesToPutIntoResponse ) { - OCSPReq request = parseOcspRequest(ocspRequestBytes); + OCSPReq request = TestOcspUtil.parseOcspRequest(ocspRequestBytes); BasicOCSPRespBuilder basicOCSPRespBuilder = TestOcspUtil.createBasicOCSPRespBuilder(ocspSignerKeyAndCertificateChain.getValue()[0]); responseBuilderConfigurator.accept(request, basicOCSPRespBuilder); for (Req req : request.getRequestList()) { @@ -614,23 +613,7 @@ private static byte[] createOcspResponse( } ContentSigner ocspSigner = TestOcspUtil.createOcspSigner(ocspSignerKeyAndCertificateChain.getKey(), "SHA512withECDSA"); BasicOCSPResp basicOCSPResp = TestOcspUtil.buildBasicOCSPResp(basicOCSPRespBuilder, ocspSigner, certificatesToPutIntoResponse); - return getOcspResponseBytes(TestOcspUtil.buildSuccessfulOCSPResp(basicOCSPResp)); - } - - private static OCSPReq parseOcspRequest(byte[] ocspRequestBytes) { - try { - return new OCSPReq(ocspRequestBytes); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid OCSP request", e); - } - } - - private static byte[] getOcspResponseBytes(OCSPResp ocspResponse) { - try { - return ocspResponse.getEncoded(); - } catch (IOException e) { - throw new IllegalStateException("Failed to encode OCSP response", e); - } + return TestOcspUtil.getOcspResponseBytes(TestOcspUtil.buildSuccessfulOCSPResp(basicOCSPResp)); } } diff --git a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java index 42ced0ca8..06cf12fdb 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java +++ b/digidoc4j/src/test/java/org/digidoc4j/impl/bdoc/IncompleteSigningTest.java @@ -11,17 +11,32 @@ package org.digidoc4j.impl.bdoc; import eu.europa.esig.dss.model.DSSException; -import eu.europa.esig.dss.model.x509.CertificateToken; import eu.europa.esig.dss.spi.client.http.DSSFileLoader; import eu.europa.esig.dss.spi.client.http.DataLoader; import org.apache.commons.codec.binary.Hex; +import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.KeyPurposeId; +import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.ocsp.BasicOCSPResp; +import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; +import org.bouncycastle.cert.ocsp.OCSPReq; +import org.bouncycastle.cert.ocsp.Req; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; import org.digidoc4j.AbstractTest; import org.digidoc4j.Configuration; import org.digidoc4j.Container; import org.digidoc4j.ContainerOpener; import org.digidoc4j.Signature; import org.digidoc4j.SignatureProfile; -import org.digidoc4j.TSLCertificateSource; +import org.digidoc4j.SignatureToken; import org.digidoc4j.ValidationResult; import org.digidoc4j.exceptions.CertificateValidationException; import org.digidoc4j.exceptions.OCSPRequestFailedException; @@ -31,14 +46,21 @@ import org.digidoc4j.test.MockConfigurableFileLoader; import org.digidoc4j.test.MockTSLRefreshCallback; import org.digidoc4j.test.TestAssert; -import org.junit.Assert; +import org.digidoc4j.test.TestSignatureToken; +import org.digidoc4j.test.util.TestCertificateUtil; +import org.digidoc4j.test.util.TestKeyPairUtil; +import org.digidoc4j.test.util.TestOcspUtil; +import org.junit.BeforeClass; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.file.Paths; -import java.security.cert.X509Certificate; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; +import java.time.Instant; +import java.util.Optional; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -48,11 +70,9 @@ /** * Description of tests by their suffix: *

- * ...WhenSigningCertificateIsNotTrustedByTSL() - uses PROD configuration in order to get a TSL where signing certificate is not trusted. - * NB: TSP and OCSP sources are set to demo URLs in order to prevent requests to non-free services! + * ...WhenSigningCertificateIsNotTrustedByTSL() - uses TEST configuration and custom signature token that is not trusted by TSL. *

- * ...WhenOcspResponderIsNotTrustedByTSL() - uses PROD configuration in order to get a TSL where OCSP responder certificate is not trusted. - * NB: TSP and OCSP sources are set to demo URLs in order to prevent requests to non-free TSA and get a non-trusted response from OCSP! + * ...WhenOcspResponderIsNotTrustedByTSL() - uses TEST configuration and custom OCSP responder that is not trusted by TSL. *

* ...WhenTslCouldNotBeLoaded() - uses TEST configuration with empty SSL truststore in order to prevent TSL from loading. *

@@ -69,47 +89,58 @@ public class IncompleteSigningTest extends AbstractTest { private static final String TECHNICAL_EXCEPTION_TSP_MESSAGE_PART = "Got error in signing process: Failed to POST URL: http://demo.sk.ee/tsa"; private static final String TSL_REFRESH_EXCEPTION_MESSAGE_PART = "Failed to download LoTL"; + @BeforeClass + public static void setUpStatic() { + Security.addProvider(new BouncyCastleProvider()); + } + @Test - public void signatureProfileLtShouldFailWhenSigningCertificateIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); + public void signatureProfileLtShouldFailWhenSigningCertificateIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + setUpMockedOcspResponder(true); + SignatureToken signatureToken = createCustomSignatureToken(false); Container container = createNonEmptyContainerByConfiguration(); OCSPRequestFailedException caughtException = assertThrows( OCSPRequestFailedException.class, - () -> createSignatureBy(container, SignatureProfile.LT, pkcs12SignatureToken) + () -> createSignatureBy(container, SignatureProfile.LT, signatureToken) ); assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } @Test - public void signatureProfileLtaShouldFailWhenSigningCertificateIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); + public void signatureProfileLtaShouldFailWhenSigningCertificateIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + setUpMockedOcspResponder(true); + SignatureToken signatureToken = createCustomSignatureToken(false); Container container = createNonEmptyContainerByConfiguration(); OCSPRequestFailedException caughtException = assertThrows( OCSPRequestFailedException.class, - () -> createSignatureBy(container, SignatureProfile.LTA, pkcs12SignatureToken) + () -> createSignatureBy(container, SignatureProfile.LTA, signatureToken) ); assertThat(caughtException.getMessage(), containsString(OCSP_REQUEST_FAILED_EXCEPTION_MESSAGE_PART)); } @Test - public void signatureProfileBbesShouldNotFailWhenSigningCertificateIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); + public void signatureProfileBbesShouldNotFailWhenSigningCertificateIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + SignatureToken signatureToken = createCustomSignatureToken(false); Container container = createNonEmptyContainerByConfiguration(); - Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); + Signature signature = createSignatureBy(container, SignatureProfile.B_BES, signatureToken); ValidationResult validationResult = reloadSignature(signature, Configuration.Mode.TEST).validateSignature(); - TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); + TestAssert.assertContainsErrors(validationResult.getErrors(), + "The certificate chain for signature is not trusted, it does not contain a trust anchor."); } @Test - public void signatureProfileLtShouldFailWhenOcspResponderIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); + public void signatureProfileLtShouldFailWhenOcspResponderIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + setUpMockedOcspResponder(false); Container container = createNonEmptyContainerByConfiguration(); CertificateValidationException caughtException = assertThrows( @@ -121,9 +152,9 @@ public void signatureProfileLtShouldFailWhenOcspResponderIsNotTrustedByTSL() { } @Test - public void signatureProfileLtaShouldFailWhenOcspResponderIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); + public void signatureProfileLtaShouldFailWhenOcspResponderIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + setUpMockedOcspResponder(false); Container container = createNonEmptyContainerByConfiguration(); CertificateValidationException caughtException = assertThrows( @@ -135,9 +166,9 @@ public void signatureProfileLtaShouldFailWhenOcspResponderIsNotTrustedByTSL() { } @Test - public void signatureProfileBbesShouldNotFailWhenOcspResponderIsNotTrustedByTSL() { - setUpProdConfigurationWithTestTsaAndOcsp(); - ensureCertificateTrustedByTSL(pkcs12SignatureToken.getCertificate()); + public void signatureProfileBbesShouldNotFailWhenOcspResponderIsNotTrustedByTSL() throws Exception { + setUpTestConfiguration(); + setUpMockedOcspResponder(false); Container container = createNonEmptyContainerByConfiguration(); Signature signature = createSignatureBy(container, SignatureProfile.B_BES, pkcs12SignatureToken); @@ -285,15 +316,8 @@ public void signatureProfileBbesShouldNotFailWhenDataLoadersFail() { TestAssert.assertContainsErrors(validationResult.getErrors(), CONTAINER_VALIDATION_ERROR_MESSAGE); } - /** - * Sets up PROD configuration in order to get TSL without OCSP responder and signer CA certificates. - * NB: OCSP and TSP sources are set to demo URLs in order to prevent requests to non-free TSA and/or OCSP! - */ - private void setUpProdConfigurationWithTestTsaAndOcsp() { - configuration = Configuration.of(Configuration.Mode.PROD); - Configuration testConfiguration = Configuration.of(Configuration.Mode.TEST); - configuration.setOcspSource(testConfiguration.getOcspSource()); - configuration.setTspSource(testConfiguration.getTspSource()); + private void setUpTestConfiguration() { + configuration = Configuration.of(Configuration.Mode.TEST); } private void setUpTestConfigurationWithEmptyTSL() { @@ -316,18 +340,92 @@ private void setUpTestConfigurationWithOkTslButFailingDataLoaders() { configureFailingDataLoaders(configuration); } - private void ensureCertificateTrustedByTSL(X509Certificate certificate) { - CertificateToken certificateToken = new CertificateToken(certificate); - TSLCertificateSource certificateSource = configuration.getTSL(); - if (!certificateSource.getBySubject(certificateToken.getIssuer()).isEmpty()) { - return; + private void setUpMockedOcspResponder(boolean registerResponderInTSL) throws CertIOException { + AsymmetricCipherKeyPair issuerKeyPair = TestKeyPairUtil.generateEcKeyPair("secp384r1"); + PrivateKey issuerPrivateKey = TestKeyPairUtil.toPrivateKey((ECPrivateKeyParameters) issuerKeyPair.getPrivate()); + PublicKey issuerPublicKey = TestKeyPairUtil.toPublicKey((ECPublicKeyParameters) issuerKeyPair.getPublic()); + + ContentSigner certificateSigner = TestCertificateUtil.createCertificateSigner(issuerPrivateKey, "SHA512withECDSA"); + + AsymmetricCipherKeyPair responderKeyPair = TestKeyPairUtil.generateEcKeyPair("secp384r1"); + PrivateKey responderPrivateKey = TestKeyPairUtil.toPrivateKey((ECPrivateKeyParameters) responderKeyPair.getPrivate()); + PublicKey responderPublicKey = TestKeyPairUtil.toPublicKey((ECPublicKeyParameters) responderKeyPair.getPublic()); + + Instant notBefore = Instant.now(); + Instant notAfter = notBefore.plusSeconds(3600L); + X500Name issuerDn = new X500Name("CN=Custom OCSP responder issuer"); + X500Name responderDn = new X500Name("CN=Custom OCSP responder"); + + X509CertificateHolder issuerCert = TestCertificateUtil.createX509v3CertificateBuilder( + issuerDn, null, notBefore, notAfter, issuerDn, issuerPublicKey + ) + .addExtension(TestCertificateUtil.createKeyUsageExtension(false, KeyUsage.keyCertSign)) + .addExtension(TestCertificateUtil.createIdPkixOcspNocheckExtension(false)) + .build(certificateSigner); + + X509CertificateHolder responderCert = TestCertificateUtil.createX509v3CertificateBuilder( + issuerDn, null, notBefore, notAfter, responderDn, responderPublicKey + ) + .addExtension(TestCertificateUtil.createExtendedKeyUsageExtension(false, KeyPurposeId.id_kp_OCSPSigning)) + .addExtension(TestCertificateUtil.createIdPkixOcspNocheckExtension(false)) + .build(certificateSigner); + + configuration.setOcspDataLoaderFactory(() -> new MockConfigurableDataLoader().withPoster((url, content) -> { + OCSPReq ocspReq = TestOcspUtil.parseOcspRequest(content); + BasicOCSPRespBuilder basicOCSPRespBuilder = TestOcspUtil.createBasicOCSPRespBuilder(responderCert); + Optional + .ofNullable(ocspReq.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce)) + .map(Extensions::new) + .ifPresent(basicOCSPRespBuilder::setResponseExtensions); + for (Req req : ocspReq.getRequestList()) { + basicOCSPRespBuilder.addResponse(req.getCertID(), org.bouncycastle.cert.ocsp.CertificateStatus.GOOD); + } + ContentSigner ocspSigner = TestOcspUtil.createOcspSigner(responderPrivateKey, "SHA512withECDSA"); + BasicOCSPResp basicOCSPResp = TestOcspUtil.buildBasicOCSPResp(basicOCSPRespBuilder, ocspSigner, responderCert); + return TestOcspUtil.getOcspResponseBytes(TestOcspUtil.buildSuccessfulOCSPResp(basicOCSPResp)); + })); + + if (registerResponderInTSL) { + configuration.getTSL().addTSLCertificate(TestCertificateUtil.toX509Certificate(issuerCert)); } - addCertificateToTSL( - Paths.get("src", "test", "resources", "testFiles", "certs", "TEST_of_ESTEID-SK_2015.pem.crt"), - configuration.getTSL() - ); - Assert.assertFalse("Issuer for '" + certificate.getSubjectDN().getName() + "' not found in TSL! Test or test files might be invalid or out-dated!", - certificateSource.getBySubject(certificateToken.getIssuer()).isEmpty()); + } + + private SignatureToken createCustomSignatureToken(boolean registerSignerInTSL) throws CertIOException { + AsymmetricCipherKeyPair issuerKeyPair = TestKeyPairUtil.generateEcKeyPair("secp384r1"); + PrivateKey issuerPrivateKey = TestKeyPairUtil.toPrivateKey((ECPrivateKeyParameters) issuerKeyPair.getPrivate()); + PublicKey issuerPublicKey = TestKeyPairUtil.toPublicKey((ECPublicKeyParameters) issuerKeyPair.getPublic()); + + ContentSigner certificateSigner = TestCertificateUtil.createCertificateSigner(issuerPrivateKey, "SHA512withECDSA"); + + AsymmetricCipherKeyPair signerKeyPair = TestKeyPairUtil.generateEcKeyPair("secp384r1"); + PrivateKey signerPrivateKey = TestKeyPairUtil.toPrivateKey((ECPrivateKeyParameters) signerKeyPair.getPrivate()); + PublicKey signerPublicKey = TestKeyPairUtil.toPublicKey((ECPublicKeyParameters) signerKeyPair.getPublic()); + + Instant notBefore = Instant.now(); + Instant notAfter = notBefore.plusSeconds(3600L); + X500Name issuerDn = new X500Name("CN=Custom signer issuer"); + X500Name responderDn = new X500Name("CN=Custom signer"); + + X509CertificateHolder issuerCert = TestCertificateUtil.createX509v3CertificateBuilder( + issuerDn, null, notBefore, notAfter, issuerDn, issuerPublicKey + ) + .addExtension(TestCertificateUtil.createKeyUsageExtension(false, KeyUsage.keyCertSign)) + .addExtension(TestCertificateUtil.createIdPkixOcspNocheckExtension(false)) + .build(certificateSigner); + + X509CertificateHolder signerCert = TestCertificateUtil.createX509v3CertificateBuilder( + issuerDn, null, notBefore, notAfter, responderDn, signerPublicKey + ) + .addExtension(TestCertificateUtil.createKeyUsageExtension(false, KeyUsage.digitalSignature)) + .build(certificateSigner); + + SignatureToken signatureToken = new TestSignatureToken(signerPrivateKey, signerCert); + + if (registerSignerInTSL) { + configuration.getTSL().addTSLCertificate(TestCertificateUtil.toX509Certificate(issuerCert)); + } + + return signatureToken; } private Signature reloadSignature(Signature signature, Configuration.Mode mode) { diff --git a/digidoc4j/src/test/java/org/digidoc4j/test/TestSignatureToken.java b/digidoc4j/src/test/java/org/digidoc4j/test/TestSignatureToken.java new file mode 100644 index 000000000..cc16b3ad2 --- /dev/null +++ b/digidoc4j/src/test/java/org/digidoc4j/test/TestSignatureToken.java @@ -0,0 +1,72 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + +package org.digidoc4j.test; + +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.digidoc4j.DigestAlgorithm; +import org.digidoc4j.SignatureToken; +import org.digidoc4j.test.util.TestCertificateUtil; + +import java.io.IOException; +import java.io.OutputStream; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.Objects; + +public class TestSignatureToken implements SignatureToken { + + private final PrivateKey privateKey; + private final X509Certificate x509Certificate; + + public TestSignatureToken(PrivateKey privateKey, X509Certificate x509Certificate) { + this.privateKey = Objects.requireNonNull(privateKey, "Private key cannot be null"); + this.x509Certificate = Objects.requireNonNull(x509Certificate, "Certificate cannot be null"); + } + + public TestSignatureToken(PrivateKey privateKey, X509CertificateHolder x509CertificateHolder) { + this(privateKey, TestCertificateUtil.toX509Certificate(x509CertificateHolder)); + } + + @Override + public X509Certificate getCertificate() { + return x509Certificate; + } + + @Override + public byte[] sign(DigestAlgorithm digestAlgorithm, byte[] dataToSign) { + ContentSigner contentSigner = createContentSigner(eu.europa.esig.dss.enumerations.DigestAlgorithm.forXML(digestAlgorithm.toString())); + try (OutputStream out = contentSigner.getOutputStream()) { + out.write(dataToSign); + } catch (IOException e) { + throw new IllegalStateException("Failed to write signable data to content signer", e); + } + return contentSigner.getSignature(); + } + + @Override + public void close() { + // Do nothing + } + + private ContentSigner createContentSigner(eu.europa.esig.dss.enumerations.DigestAlgorithm digestAlgorithm) { + String signatureAlgorithm = String.format("%swith%s", digestAlgorithm.getName(), privateKey.getAlgorithm()); + try { + return new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(privateKey); + } catch (OperatorCreationException e) { + throw new IllegalStateException("Failed to create content signer", e); + } + } + +} diff --git a/digidoc4j/src/test/java/org/digidoc4j/test/util/TestCertificateUtil.java b/digidoc4j/src/test/java/org/digidoc4j/test/util/TestCertificateUtil.java index 9d88e8b13..a72688a6c 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/test/util/TestCertificateUtil.java +++ b/digidoc4j/src/test/java/org/digidoc4j/test/util/TestCertificateUtil.java @@ -1,5 +1,17 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.test.util; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AccessDescription; import org.bouncycastle.asn1.x509.AuthorityInformationAccess; @@ -83,6 +95,14 @@ public static AccessDescription createOcspUrlAccessDescription(String url) { return new AccessDescription(AccessDescription.id_ad_ocsp, new GeneralName(GeneralName.uniformResourceIdentifier, url)); } + public static Extension createIdPkixOcspNocheckExtension(boolean critical) { + try { + return Extension.create(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck, critical, DERNull.INSTANCE); + } catch (IOException e) { + throw new IllegalStateException("Failed to create id-pkix-ocsp-nocheck extension", e); + } + } + public static ContentSigner createCertificateSigner(PrivateKey privateKey, String signatureAlgorithm) { try { return new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(privateKey); diff --git a/digidoc4j/src/test/java/org/digidoc4j/test/util/TestOcspUtil.java b/digidoc4j/src/test/java/org/digidoc4j/test/util/TestOcspUtil.java index 197605e3f..b7b2b0e82 100644 --- a/digidoc4j/src/test/java/org/digidoc4j/test/util/TestOcspUtil.java +++ b/digidoc4j/src/test/java/org/digidoc4j/test/util/TestOcspUtil.java @@ -1,3 +1,13 @@ +/* DigiDoc4J library + * + * This software is released under either the GNU Library General Public + * License (see LICENSE.LGPL). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2.1, February 1999 + */ + package org.digidoc4j.test.util; import org.bouncycastle.asn1.x500.X500Name; @@ -5,6 +15,7 @@ import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; import org.bouncycastle.cert.ocsp.OCSPException; +import org.bouncycastle.cert.ocsp.OCSPReq; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cert.ocsp.OCSPRespBuilder; import org.bouncycastle.cert.ocsp.RespID; @@ -13,6 +24,7 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import java.io.IOException; import java.security.PrivateKey; import java.time.Instant; import java.util.Date; @@ -55,6 +67,22 @@ public static OCSPResp buildSuccessfulOCSPResp(BasicOCSPResp basicOCSPResp) { } } + public static OCSPReq parseOcspRequest(byte[] ocspRequestBytes) { + try { + return new OCSPReq(ocspRequestBytes); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid OCSP request", e); + } + } + + public static byte[] getOcspResponseBytes(OCSPResp ocspResponse) { + try { + return ocspResponse.getEncoded(); + } catch (IOException e) { + throw new IllegalStateException("Failed to encode OCSP response", e); + } + } + private TestOcspUtil() {} } diff --git a/digidoc4j/src/test/resources/testFiles/valid-containers/valid-bdoc-tm-newer.bdoc b/digidoc4j/src/test/resources/testFiles/valid-containers/valid-bdoc-tm-newer.bdoc new file mode 100644 index 0000000000000000000000000000000000000000..2597bc3caffc33d1ca4ddb4c309fd93e32a28690 GIT binary patch literal 7199 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 Date: Tue, 8 Aug 2023 09:39:45 +0300 Subject: [PATCH 12/21] DD4J-896 Update Maven wrapper & remove unnecessary Maven wrapper files --- .gitignore | 1 + .mvn/settings.xml | 55 ----- .mvn/wrapper/dists/apache-maven-3.8.5-bin.zip | Bin 8756655 -> 0 bytes .mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 2 +- mvnw | 215 ++++++++++++------ mvnw.cmd | 88 +++++-- 7 files changed, 224 insertions(+), 137 deletions(-) delete mode 100644 .mvn/settings.xml delete mode 100644 .mvn/wrapper/dists/apache-maven-3.8.5-bin.zip delete mode 100644 .mvn/wrapper/maven-wrapper.jar diff --git a/.gitignore b/.gitignore index 41013016b..ed84a0bb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/* target/* *.iml +.mvn/wrapper/maven-wrapper.jar **/.DS_Store \ No newline at end of file diff --git a/.mvn/settings.xml b/.mvn/settings.xml deleted file mode 100644 index 704500898..000000000 --- a/.mvn/settings.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - .mvn/repository - - true - - \ No newline at end of file diff --git a/.mvn/wrapper/dists/apache-maven-3.8.5-bin.zip b/.mvn/wrapper/dists/apache-maven-3.8.5-bin.zip deleted file mode 100644 index 4217b49aede0f0a3f825fa7cece79aaa9f624340..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8756655 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

a*C=VMft%303I#inWlFR2z zR3XKfydLZJF9Z$5TC+z?1a?3tQ?r>tl&Q68RCb*(uI4>2No9P{Ly(O*whVfG=misz zv_)?aXPIo>#o%{gbRl!;(;RjxR$1W-)ql#bJqI0xu?_aj%=ryml?+y z?>|d5eBX1GUjxktfZr>7Q3SL463gAC;Ck{h?8=X{%U_!PO9CNxdCJ|%N7Jv%kJbo3 zL4C_Te2X)V10aDjaJ&SAI`6?5FVX@rn9npneyb?^;tlTX+66xIc*(Q*)`WZ^_9}S^ z_z~>Bfq%}$VgzUeVZgmBBc=i!1bj-nzbZ2b%8v9=R|qPO$d=wKke_#8-#d&RQGN)( zC2Y(rj{BA#9Se3weX-s|5^~?_gZrG0&{&?STi!Y>y|?&(LFL0Ryx#Wsyz3+O41c}d zW)k{Ds()}+oam{%A;tR`{`pOrNOKmeMZKDS^)h&}ossPX|m>F6RgX(2(2N2dYl zIL2GT!aU8e!|ZUE+pQ+K>WDF0*gbsP@ew8BJRui4%zW)yi0f&R$CrThZG3q&+WD={ zJTrTzr`+PTt}?q>1{TnUJBa&cwr(c0nPcPh=dfgy$qEDYx?DiaNTLNF8zMo==4~#T zd^C^o^`{Iy8?kw$iDLm?_+%IxI>P}^J=OU)0VvT@w*$Ox9+ltLAItuQUGW{^lD~Uf z$kXN4&p{t$r#8Uw%}m5-)0@Gefu5C{&CfYWMT^s<`(>B6I!e)7lCgX#lQ7)+$^j~! zadJ_bZ82#Zd4vu3DSWJGabU8?KSjcirQ148W0y%|SlND~%vg|~Qk~1WlzGQ7JDW9p zh^W;TT9jLqOj9zMCa8Y>vYO0sc3fkU;-R@XIZo%nU2tL5jk;VM`?jyCZ48CQ+w7d^P3o%3g!IjX^ z; z{p@B|<$zh-UCx6xM^1wzLc7N#*2LU@SaRg3vWtqw(2cW#lm+=sm&{aF(Z5gJ9X%_S zmoW!R@=8{Vi#d&l>lNNq8i})`c{`7YCuenqVCKw*I(!0my4^hK;E8Kk@%gg+@+1df ztAdp`%#6}aMinWFJ5O?p8_oyh9v!0QX(6ZYAUgH!1E_Yml3vz@%P8XDk|RhmLmlIas_GnE z7V6f{vk&F$B^1(i0FV08m|OT>Hf@aCCVfnBtD9Er1G^tCS=*4Uacpv#)g|Q|YrZK2 zqb&$gO~Qs_*88<&`5TAOlKKg!3(*@sk|(zWNu9ctanBBB)@=-C+D8&a7wZtGX4FGU zqHNR+4B{}E8)>ld)JfOwyMS@W#+8PH*mB&;bxw$&V_}aaO&mC)xUZ7WkEY#$w+YQU z?yXHG(MX1L*oT>`i26}Qnm~PQC6QmS6s{$qTd)<$vR!ii8dvIEiG%OUhwAsAR3KtH zde+3U=xbW*&rxAUI$W~7ck(3XLRN*JKLGSqYv)t*ujiu#h&Gi@NnM+CZdQDl3KONz zW2jDmIoQUKFDNQkCmfcavL0F%J$gU4hKH&+A#B@>L(hIURSONIqB+Di%?W?$ZnTNk z;!>_2;zuDMqv{SS2&rT)l0H#|V+-g{Vq2waJNTyc zD{bmc?~n5^2V^yS4Nt>UA7vux^R6z8tC4(f{mXlhhMmGKect zHh@q`2WmaGV_&$*#-DVWWK|PUNY#O{HMdu&(54g2V`Ya|meshIa)q$jiaPJ>E+}(~d&^toXUl>o&Ao_Gr^(+x6^BCuKRxbvJiB zCrrA&l@69;ce-VNak@zvvfLU}$B7A?L&kcPa&s!ZU}-}CIFXFW3=lG(ECAA|?9@CDIu76cV@GCx| zLNoL(Hc;npZ03e;=f$>^Nh}Z}N>;Or?Y>WEoGhrQCfaUaqUx*q>42q{3+LxAwizS{ z8NyjUAQjW18f6zEjuv|1sp4JQGjNrvn!i2Zn6LvrU)%oc4Lye4N$)v(%Mp2A$rr?h zu0%mU=oqwfgiSTeCQZlh(Rzi@?|ifX$CJ~TyHUa*NM8{xXu=JT>iqe!sZnkpb+Li( zCSTnt?fk-#t8|;P$v`oNiBwk)&jS{qjUV`=k)A9sZ(EHxsEr=fVgym?wJz72reM;p*Pb54Q@V`9R#Do}RXNRS13SlO0uRPMafV%wwG`1+ zR&2eNG1zUn50Ks8h^sKc_ib|jlVJLQd!#sB2!8~V7ee@HDfnjzHK+#u$|EwQMo*X> z$O&}ZPQZH2T@uINLvb!Bt0qw0SbRj+w#2tna_w$ta*ovouv{W87lYl_rR{^E0n z>&2Jlj-$8T1EZI_la z>@yU3(F9;3$+7WANaKr)p6b3LcG`@{8PC~sdLXA}&xKO=(VN(QC!izZjiR}M%y2+m z*`;Yk8kvn9Y3!wop{(vD0^jny(Tnf`_ zshXH*B)CPN!@g}?=vfar*FM!7PlodLOl8>jgqB8Fs3Ym7sA~*^*Fz&!q)HbVnYdaM z;{8e5sT7+FU{Z!<9rdD30@I+6K1qJ`?m95_CS)1xg(_&q|PP?rGYdJ`D@c(Qy-X%OjWyz%pQ2mhSC75t&k zc$16cz2wKI(!5?Xs{SHzP1>8{;$G^J`6FcnOgir%8X!&SJ`*`_bVNN$o!^*2Sw$vw z&LrPn7lg0|f7)l+_MLBk)8-r(Y8>)01?h~Qq_H?^Rth7JjGlfQT4z~hw_ahd9=n^W zbrGD*j|6l`^4aaag4Y3GI=Et)mN)oN98syy{c#cr9=8NOPO#*Bk$Y&A-qI5Wgc(HH zm4wt`G6D1`LN$hs;ZRL9LJI$TaRGy++_m3#$Hu~q9MsoE2Pp`Hec-o%z@B~R2Tl03j0X~n?@ zyMsox<&p<7TkP1r^^KH0%c7)?zZZ7CJTr zCH|zCa~F$lZY`iQBi?4=^*&b=N;0TwjCFPF?GCgTwhferPNRQ=x)Ed@&kh^co+A&f zmD-Mxbwn__;|Je^s8zlivVDO>zJrPygStqRH`KWrz;hIUA2Ykff8pgPN7!ZUksk|u zuI7z8K1A}8kJ$%%f!0efeop5NNj)rNKfq)4Vlh!vcf`|eT=W#6Sz}me^|_+F@oD>Q z>m4>UOK_XRbi>_+B?1Skqekw0GPYu0n(c%owoa*6W7~5#hVvhvCKo zG)5jE@=heIRdlsOUhe4UVq}}FWV71Wv*N8=?k;M2=;vC7FK|)&IA|^#8-X^%akZ?~!mwex)m-7)(xI!4GvRZ*&Es|j`-4ca z?dkWIz?Zwv@%wR4_j_!~Z?b$*ub+E59B{QfspVYq_~rdCw&O=2FN!BeSURL6vAhvz z^bX27b?ghW*s1MpQD#t~j_DN&&!imgt<13%fM(vK(E{#RD?l}`T*{L2CSmsRkruzI zm7kC@$a-4%$6(U?>X!4c5Lx2dIDCC^a@t50-HO&#C4+iDG8 z)-RK5WivQoj9QA*yE&%bXaM({Y`f!Ds5UQ)?^}C^&JVi;(HRov#4z+}1w0NM!e?z0 z=1LCg)`ql$juz;*-Dl=EWD)4mms%LWt^)B=+qa8SB(276@99Eci^YTVzBK}PdbO0)e?wK%)7r5r z8Sqoa&_J1jy5u&AlKil8$@+HTf)X6||FrfMP<1WYwm88(xVyW%yE_DTcY+3Y50K!& z-Q6X)yF;+xPVgX~+}rQnK>yB5_wC}0fedQSeX45DRlBOrnto?s8Ch+z`)6?NfW#dM zKJq133CTX6ET!Q`rd-}Y0P+UmORrHTEQw1e$_(R?RLz8r$Tn|lw@{|T^!UZlLH3!* z(d?1%cM@%ZA0SZ1MDIZ6fK=kg-o%nBIt43Xb|>wdYeM)GbaeBbD(RP zQM`EzM}p`6t_ORvM2-cdOs()FUJ5&Q$4vlhO@}ROvCt_j5AdthbSY78_pA(+3rcLa z1_5QoPLW zlD02mm)BF=sVfIr}l{S)L`f4Wc z2;4$SP?^bb$Io^oaMeW%HP>}goW49i8FrbWjIWFZc$YZQB{QLmAY)KI`ZJ_gWWhTP zOc;D4!L_*~+jL$G2=KBoH_rF3hox7>P(td213$Nji)L*2q1J+ShH#t6lmQr*XV4XQ z%T-f<3Et<+eoJOJbFqbFU^z#|-V95F5en9Be)JVVOk@G2W=FY#wn3|gK1^C&;{vFf zgNrFW0~W1*AcExWjEq9A0u#c;M;RTVz~vj~3w)Jbm>w{}cgTz;sfJxtvF>ye)vt?l z=FHw@L9zkmvySx1EtxY<24}+^L>(-_!}y%ukjhz*pbYch)kxZFcCk4HIr0Z2E0ieh zaFZcMp_S@U)J`bK7;O;6zP4X)P>U0oFA1p4IOktSVVetM@UA98YDI2^)CQq=?+oFU z?@MSSy2VrrJZ(vq@zz&#z?r!CkVzy>D!EeNR-z2C76=~kWm$_#x4gGKY2sTYbOawu&aBR>C9cM`sf zJby32oAJ>W9(Uhc{+cI)H**5hrTxs0;y(O~!mgDY)QPx8M^UN1jIA`fUIwrtM z4nW)JO^{(I^_z~dn%)ZXG0*DiPU1h~{^G~PK$286Zcb7Vkr_=CNFh#SDbRBxg?N%d z3S!W#o&&za|K?8VR%bOubmvu4i02M{NY zIOT3mZZw#i(jh|wpzT_Q#ex-!Hq}nrYUw4ZPu%CEMky}Qf55sj${oh_4jSV=Pwkst z_otC9?P_?1E7g1__6P-(B~3MQQUOH`Z4F|!0xgLT>BjTY|t8kzEsN3dhG@lXz1Hi*7n z4V1P10*df}@U9vPkcyLraj`7-m-^M1A5#D|&8jb2_`;6b57-SF3%LL%ozC(ca zF&Rp@!Wv*w#i^aG!X#YuBCWPWm}8Srp!M8a`KPIZWeDU{Ph&bhFhD~$Ax z)s-M2%>paynd^@`lr$zhRl z{1cPH42&XaIM!@@-9hm+NJ?g zYf-*xbJfB5oz+U(L8c^=%TtEol8GFiLHXfkaLT%LVY{wpj?66K3O6_dBMYot5ANHo z#hxFut1=J(qq_N4fx1i}qGzF}sKF;jzyfyEU=~2Xf(2&{Empyv6M{0f?ychj#Q(|ICh$h>%UyntEqeEM~+Xsu6ElusUx0qI)Kqk{GP% z4e(%96|l9LJJw2j=siHm#hy$e+!q2(RZ3e($>In(NQ`FT-@6RS`9&_bB^Z;1xo|;Nia$yy9xP*snX(PSHOi|1chN3Jkko`V;F%~Jm`LMff9)jr;N{_5O)YKY8Wi!&D` z;Om_~7v!NIzBYXqnZrsqLn#BgJu@q}D(+}P5n%!=OBq0oKZhvf#*!mIxc(@hChV44 z>&Wnq(#B3cGzcBTHS{?L0x&nfL;fx{6}@Kml}} zMC}zyRT6goKB@;^p@;6{(9H1$9IMOZ`_2TUau!0>EvH+qnk>gXoWd*DJ&}TUaLV72 zl^|@KkI9%FBN49fK6+wzenngwxytNg5l@#T!S$U?us6L&#<@q2A0Mr_l`MXIjoc;z z;T|N@TXIiz>*r)j-M-=w?5#FtsXi9&(hTrrzB)mBin9Ge#IdKNuK-t!x9gOMbSA2+ zw9^p;t1CChMG_jt#?K+{bvE!OZ7m(;2e$5^L;vL0i3KMHcN|i*iN(j=niQfD?@XIo zVB*1dsu65tXQ6t^PrGBbihEE8tI|4W2q;9?CC)}>RxT&Lv66km4;_-1y9X}Xs3n_G zlbBAB=-)BIf((Qk=!@Zn~F*=Msq#V zBuP)nmAY#h_wodVP}uIEltw?li!$oM8VqLlF4pV9TE^-Orm){C4n*0o4cWE5Z=3Dj zEK7dfQlJ^vzG9E$)nHJa4^CeBwLuBwOaK$ef%>K)mLPi5Au+KWI02z$koaa~?;M+? zo3;2OZirD;7lRK|OXX>z?EoTX;{dhKW^Ox{(BXC;bC7E}d!z#3`yy;FHP1!F<&@%d za8ol4jngyn!aRJxO^dYMPepoZrV6|wgKqw_XMWY|0I3lICTez(!12!A_~sq#JDg&a zu_Wl_mO1Fnp)zaJELD5dF&DXg=yWF^*}h}V%$p3|4X8lBP2hQ8?rEz)mZGm_ULJ$W zWnx0wek*qejhdEm1GA-|v-FAyOjtc7%M|4VyaQDEPBMUY$3;BE6u7$>twbMN4TC=zC zM}Xlh_;oCb)HWF`t#LG~CDmXKnCe->&BLJqP*?FQ`=YRp)pu3GJkv>9qG^0X0fx6| zsEBnQw9HZ)-`6+_K#w=N_KzG(^Ut`OK4MTo%?R!m$}g-oh)ES_ut{LTV3s;no=ZYB zhE-THX>o^7y8H1P*63+P7-OoeB$#$4RTU3^)OB$E(Cy}OmnV|d)}J|NSWcVN-n!#I zN6Nhn?SW(?iVmIO8&Cjo-0gv0vW@mM;!3v%<&WNuA9{dt_p44|-m%{z=?EX6PB&hu z?ht$M+{ZkCM9Np;#!bYbb<~`jFcKUmBlLsadyTmp-;U;{$coADcs@MEYXxkK&M317 zd2bJQnyg-AJ@d1l>{t&fC(XF+@ADjY+vD zp**xH*i=2yZbTbh{6)`?a^b~O*)K1P=4AHqqbRAwh1(i@ee$3fx+9FpWB{r~--G<7vPcJ%sMRT8^zBIk# zj$r;hoA+e*-X|qzQwicwi*3lfybf`f@ED`|j5*Hqep_FQp|cxK0T3=W2p6#MQl6MM zaKp;q{2F4g5$Nu_>aEQ^P^{6sy2;aPA(1Q??EWzU7i4R|NcVLkM8E?JjWCH`{TJ=# zRtb%8|3lat-d7~hjl=fp>8!#H`mV>ptSzP+??!^;_|hukWxpSu;e3zB9FDjvV^eHT zHQrVzg33oHgfU&52?-yxX_qb>6<;@H2d~07^u16C^Lo`0wAM(d)WO?Ra9TO6m2-~J zUy}zUcgravBXJKKtu#P5l32vKjly(T=8)n4JZnO}_p1(x z(-4U`v<%!liRieWhjBZGy@HZ^^A3V53%a(HmctpAq5B@Yr@GDDHS8AjqN)i$+GDwX zb=K{c7ZQ%tr*MwTc}?n^Vr!?LM>y|f`yt1?{amSZeAMwQ*i~|*VrtT1%4hvJpQM|9 z_AFArFs?zFx#^BYtQKOV7G%ZrHlF~2APSwJZj*wN*m*8?MqYFtmKKZY(*PEf>4yzy z&1MQJZi-@;VJ;CwK7L6-)NM7Gd5L8Pwt1v8=x~K=ar=E?5q2?z#chg>K|LsfI^-Bl z8REz)q?|&K*Mr-f;7t#IB%Eq5vChsx0sx?<`@4w`{#*$BWlrB51xeY@eDDvo$neGM zz_{RWZoovB-fkVD(B}FAT;3hu6j+RgC*JeKeaZ>x>GI=k$2Cf!_7B5g&fOhh<^1N! zIJvv{eUQ={W9A#3{1ARXJe5k7ngN|*lwN^rr%gji{r18kS#+AFNgtM&tcWNyX-+O~ zeeK4T(5K!EZY6!89(gY4<2$|!fu@Ypnx2bMg-uw$c{~=u403Kebht)>`gJX0N3)f+ z!cO3V`~DpC3!^^UJA-9DTjp}vjg0rOQ9_bUCWNBUguCucf*kz@`42`wnGFPucp4Q- z4|{`O7vEvAt-smRW^FBK%?f#4nNSfe61aAv(@8h=j`wq10QEwRcvGJ6KFuq1{{nIj zhp#ncX#^I^wMC=4@q0+&K}3|Y+a8FE#9wfXD`aWQ*+=qBV8zC`AhUC0O4Bb;%h|^3 z`uEft&t7f3qeu~_!3;@fmPvRufg58;?e)j9u4#I&f)*eEK+P|cCD8wNZwgyG+PnTE ztE-BRrJ^$0V`}Yw%i)oP<_=muovrDtGxeh~pJ7q5(hSTl03g5hV$)^i!^Y(YFA079 zDWQm-u8+b*?sOdq+@=J?68cQ7=(yp>JzXXnO&DXxDejz&rS5oUZ4M)ETaVwi^0qlF zd^+;_j_s{gf7ET9&7~HG+Q7C>OixaD*o~aqz&6k=$q;!;-`Nd~+S|a^(JfA+y|o?} zKIy?lxQ4=$7H>Ne2Cu-Ny}99vPSHDhCM+Y87KJf8Bta%d#&EtRVcx={uKX>jqx{{O zuba4Z+>``D{)9kn^0C_Q-rD2Ce$W*s6!4TSfwFY<@29!+ zN)x9j7nHJ6ro+*hH4*ca9L#t9&38PkD7B2`%NWC@R3ZcjMAL+8nb$)g>u%meTbQ5?E3m48>}-y&TI0sVmK}(UvP2;o7@FD`vw0I^fi=QHc^#w7*u4-4i(TS12KM}MRcsw zS12kSSk4q=8O7;9nLx-&@`|%9P-=6zC^X(`0{}s zMkWy1o2H!;jfz~Sq#NH>s`Ssw?vbCwv z6aI)5a6|T2VwWpll@I_g~Q1)9y@V0ue zS9=%NoR5BsNZ=i@bDLxtaDm!nJkYe4C~jYsTpT;*X#>z01YH_Q5?RdDo+PjeWc-+Z@(*!t>A_R38*I$Kf$_OFs&BQn0hGC+4Uf{Sb0M(t4Pl z&la2Fcm$^THYLGyH$SVydeRbZcV{*{pj_4Vm|Wplbd@KNmkuad&Bxtb{%cIu!%y3C1I zh=O|Vj@Pa+T*gBQwe>DA^@c-8JpzlBdEW$JoLVdzK~Z&ponXP9`iETK0e}zh%Gbfo znXRC*6WGo=1>R~d#>ZGm^{m(~J|?sSe}0R=;RJr)aUl(@rUu*rGvi@^6a|8t}m^(W8izF2|+ z0M!1{6^!qrPb|l=;ku%&iFdO6An2EcFN=L@S-fKLIT>1VRrGY*sKajy{Lj zlkAV69Dutjihd03A3?-3;dqqTaFyboTZj9}<`}?yZn#s3J_xzCa&AOFs3RIUFk%L~ zZM(MDbM~kw<9wMzFc;qw{S)JxI1T=t1sOVc!8D=EIV2>=$lk0S{8ugfhO8*9%JmOg zg-Zr>$z8@|)!DQQ{rR+?F~3~-n`5&r?VrjO-XDyG2QlcI-p#QhFJaCfrYEy?Mt=T? zBpPmje(mT}O{1Ux(9JXc20;g@M2&*>mg>ej+CQ@X{lLzb%o)*8Bm6L8C^JK}kq0lB zz=h-CQFXR-gk&cBq_RrBK0K*N)8X+_!5d`ZB73zza&qf(?G|#C6mh(jYDS{kh||{f z(vTg6OdqFs3dzxX>F2ZMJd<_gg>M?qpf~JjQpSU%sZFJ!jD61ucM6ATe{|#cWtgY> zQ$#NQWisyHNr&d(X#X^=GI9O4c5r$B9bkU_A3qv6D*odS|8S{PmUO@rhJO&zFf(u! z4>#asfgpkFo}pB~BVc175t)O)=q-p@_t~ zCci=ONt?e|=%N&O6DKjr&CRXjwam!Ixp8nW#1{?*R`EBlvg+vVs69KRt&T+8r;Dy^#ZR_hp?6oG(GT~LmfLq`P zVpgjoN2#;A6qy>AB_S%TFN)AeGa?$+W#SE3?TCxC1WWI9=eHUsk0CPk8)Pn~hq?is z1FLPf&_?bTZ<{etgWXrELMFQqwv#LtGf{42?y3%=u3#m2lcC!XldusInm8}^DENnn z^hw!ZnTsPk{aQs&R$#~`Dy$yM7QHh`qKD6%-G^(@zt9lPT8~wX6OV!|Wl8o%Bf@rC zM0nTXSf91zS1$H@lgfkurDd9O>S@xx4ka}^cq6E_0wc+QVI_>@!79SOSyZ0ya$Ws1@8XD)3HF1ynJmi6r%)FR+KY^cg@%kb;iwK>i{}w{7P$Lo`H-%p=I~ zh*>>)71K}WIl?8pqv9?D(K5TxrI4xyL&up0 zDEuhxoHiGxU8E~Z$nN4;(CwN~$M7m3+p`5JXPHQQKs`V*Q~F zf_vmAWxxOc%ddW=4gCL(Hpn`dm|CNEir)B26?aX$;NGJGWSr%v!y_dPtD)G|i!i*C_BTo?1~7=Du=ksi0Tk zugRHDY+y7Q8M?pzK5XL!pw@{h9=_@f)Ok%80<#oDK-!%f*d*Q+^RY)%!Go%soBT+! zg1DPh+}PS;Zv2D~uhp!{IT}?>7L}__Kd!}KzhOQfleyQeLw25i|KgZyg}oHB)rdpc zK++91J4urZIoOI`P`6&UX+}HC&G05_m@p`9+*g$)RdBK{2b;s7!=Z`B_KMeH8h8b| zctFyiO}pZlb;+QYBA_&--8+*Ynw!_e$A2TScYrWj0=1Q;jTxrbkrE7Q&YHMxZc9OL zD5Swy`CSf{eTp~?#UkXx03?309#;U znm@P+vH&g8*Di}puU}R`>03D0Y~28U%XRDN+WYVgWz=N&oSGG0jg8yBDpoV?fCs5B zHB|-`fK*$->Tu3JE4LAD6(%ub15w1O+0P6H&Iy?=D~qff#~5Tw#)pO;>% z_!L|Qz`jS)qLj`*3V%H#HeZBuT4UM7qm%2ta^ z4^Xp$gd`EWV`$NV51i|xYRcaoZb-W&XHt9dHX#w|==_t5>v|yf>jM`Jt9+ChK6q>; z#S`$T53Oreit8dAuR+d_j2DTf6`c=FGQK*6Q(<0j!5txpjN7~AxBzutOc}g7?}IFe zKGo&C_s_(|=+DetDcjK@!7A_0T+Dv-K6l=A@3a4IRjr6{s3he6fr;^usLV`leSjfo z9P1b^n{!NLSAbsWyhRSZ5owUBOsZFVV_j1sOA1&g76dm|p35l1By^yJWUfHT+V<8n z9A~2$W_@VFJyt_XTA5`$d_Y8go{VBJf5vk5^Zb|0*3xRY2hbnda8j~qTJod~-M`d^ z-^oe$zuF+DXK!TfC}L*s;P_G;G;JoukRNizH%RKw1!&_cEQXJHiY^Yda59as9f0#VDise0$?BSxeweNFwd57gUHQP7`fLZbn#5Xdd6) zU!%9PFGcAgf6PSd*hDK`rC>$3u0$;DhUbrjd$+m8!OB|S&_B$%PeCm?vdugKyJcD*QMPWtJ0tc?U?wn^aCv?MO$!2}+p7}KDK%}`vZt|>EFSWZ` zpq`wmo*1q+li*bOl&23}7g9jmR9>NezOix!P^0=V6(}Bp2)mwQNrCz zB}&GzmlMIj%2XXIs$ZK^=6Di0$_jf5&uLaD%rny=Q(c$iRb9wInwh+`^Dt9`2&IZu z6wXjPs9VC00}?FwRg(joVA%uNH7#_HEX}+D(}14$10PYt9pC}BD{ulHCejWT7`emy z<^p46&pc2`e_W4sT{a(ee~?+s+rXV zBN3vlcl`K$4>`;^nQ(>l11t&!1o?KdA$Lx(06zJKl5<2eJih#$fVP@rJZ&a={AJd} zJEf#djTY|hi%YH>RR6c9n148Z36PLwKWReWFE!zJo;Ckh6BLasjsHK2kgBv|^W$NH z#m=L`-E4x1S4XwJ$TH9O3q9{e)ZiAQkp?E@MS4xfN9 z5Cl%lbu#?=;>CQ*h8oe_#M02g5bMgw$k8XS$1_ZC&1lw(L3S6O#4yuCuo!~&@DTj0Kv{z*+cifn>_R`cwhnxpZXG*s3 zl=h8_E+Y1)WiWA43e8i%T0`8MaD%2?`G zbYD#j;v}|JPOP;!z&^huE_WKo6i@#WK;>d>AUh0JrueBYGdF|xj1DbgzDg#Ub}}XW z2-XbEZR=bB+!L==QSoM$IY>y=`3 z+bjPR&4HroGqg3_;M^In!0VWWSH@%;15N()#v=;J`$DIjWpbJJ2O;>jFkxuQYAfG3 z2W&_#kVIy5^s3_?fGK?tVtNF0!^H(3QO18v7P#;I)`|CN3{vbt>51rlkoR-c^^jOA z0+bEOjwyH~Qzf{0(BJg#8zOaLd}&WMY!WK_@@*;IBr(k{xUD<~;kYCnRi0?7R5ib> z(maoLWrC2B2&iX6@0MPemu{U{*h^`=O@s}vH`8^ZP1X%=*S*U=O0XJ<{jwT*Rcm*ylVd^FM5D!&{`fdhcvLRKv+q2lY~P)QCle&HC|7tuCC7a%a`1DqGrc;e`H>kyQ199 ze^Q0dzf^_a`F!zTs_;wS%yZ3&lZJ#b>Ymhew?I(b84aEGxiAw)3%*@?JR=4S!Y%v`*WJgNUx!RS6;l z+yy2Xg0>ofO{Py76NzB<`Ua_JaNm^-&_qMZ)hW=Eil$6IX)7iUi!JytaYzCq;?Sa! zOq_k^k0P1|g+S-gEbX@}b|LNWVL%xvI9~Ja(9s%uSYAY@*<235V0^=@$(<^~HJ0Il zoVbQWoaYE?-E5LtICe56-v&0Ke6$_daA93+x{iSkuOdRbU5eD%?FBjQEsGijV4*v1?{PsT!TL&XW-#CrV1~)aVvK&)#1MVTBj{|_@L3nzpSfd9=YtQM zrM6N4&!)1lSOu2b8|C^BTPeOOOVJ3O&g@gI`v_GX$uaH)T`=sjr(}(=HHE^~$QC$I zZJTM?{2}gk`I?;2+^xa9a$sJ&s?^l=jka*m_LiShHy=OdH8uzZ>D@nqqHADRtMhED zE-7=JNMkaba9S>z_u;Vs-(>Wzrua)AhP-E*M7MT7P!=RhhgybqmY#A|>;^qI2qw9{ z67etmm>tPuVhpm4R?DFU80b?LhNV0jAo_9fzz~K)Eghy#uazpHflNI}hQ?Kdr_LVE zS(G1)+wdC%TO`o@XLlgCanaV~G$TCXGWpsYlQLvRxV|s7<0h@+R?wLV6F~~MI2Z5f z=a7mS3qM()s!4%}ti&n+BEc9CnYlCdj8m~0sgVJ_|*C5 zN(k6wBEpJFG}0mu120hiu|oMjONjO=6}XC%|FKUuK-z|0q*`D;Gf^9f4)~< zHup|Ef0+Lh;zxi#GtvK5WP$%v4qF>58e4lCTO)f%Gb4we8PlH_310aXtAYanY~%cy zR_(7M4DxpvU92pB)qu}O5;*jqvhu4MFwbgmLcb8AUsXkaR@LQY)qm9?Kg91&*jI4n zY5X$+|GC@!SLyf_jDV}7k%O{=l%S2ZwUNPJJ0vgR(Hu*?@nr;47ew+dM z4Oo6dJzK|rbF;|dj8!Ab$$b^A3Pz|4rauw$0CO=+B4G2ku`vpc@(MIaxaX zU$^bgPTbF9SeNjB>aYG!iu02tH0d*rT+!cl_-Dm%g;t(G|xzoRQ_F;zh8Cg^B}RL{%@qidU?q|yF>{;gJstEFWHX0r2N_bNbniu z`#1j;Gpd(_KYP|ZpUYBd|93o=UNZiiJXqiv`hHt4^ayttY$y|jV^qtah6w7+0b{{=%vTN$bN>##U55D?lw!{mh(q$R{v)fnU@ zV&j!zgPD*IZ#}H)wg)O86_HYnCxsYA`NEtq;?uIY1ucJr z_QUA>k>l%rCSV|i4@l|XjsW66Uz(kxc&{1 z;NKCg>|FuQ_QtktJDFW&d{*mgGNCt?V5CZgl?by>@jrws$cHIR6b7<{w-aTXQz+zri8? z3+_KSLf3b|wHbvwvLQ|C3@{#_dt^!GVBGiT*oi z|8HYr;!5HQV&V#-(&DOH+FPm{Tu1>Yb#u6*O+Sf+Zbn!+Ia5T!6)f9JyFErVOq6vO zq}@S2FC3mye^VIRN1y2th!k(7KDTzR>qjz)^&#(@lEXbW%PcfU|0f(3S z^TAgdAagx|6iJ9feyY1bYS!F)S~5Oz1MOJJP$P^%6asd#!WAJ2%5JM0KTqfhbElFy zeFXv0t{I~;^lekB%@O4}P)Vss>0oHX24K2zr_=`vtFQ0^ z_L<`ur<8w|gQ7{GHbopIv?3X>4oaYJ8Kk&rO}V;MYRor-k?JSGJ+zE-enh4L3!F`3 zal)Y_?zXQH=x=UaI)Lk7ZpAhCpZoa-LppeiKz}h9Z*jcT0`jTLju zgKFe9-s?_6qD*+d@3s7MvitFR8fm$d3uPi~hdmTh3eK?8ja#5;>B*UiI0teWD+d6o z0{q}38-h6Cxl&~@B!R-VxZ^`x2CGIrXE*GR;-Zc2GRIJDGZgKRy)_=}s7kVz-_yx5 z2G<#=U)krgzp)A2@#p-5vkHL~+%SMm&~!B?Dth}e%B=8<;y$1~m^<2g$Re5R%^Frv zevV#|wm#TmmVPbrwSfMR4Y)6Zxc#kM{AGKzM&guayg~_V3w!m=YtB4QVcjzFsM&Fx zZbp>k-pJqC7Jp02<8==f2f1W79}!yZjLX4cJ_bmGy=LrzO$*^3`?84k7kqhmgRAYO z6}8cpEd|lnjx8I3eqJ}HRWX35J9DDU;>DXkOKh5nWvAKfj#t1gCwU`l_M-W~aZ#l! zN&12dt?5z5Br&qX+*C)XR>FZ=mOAUIDu+d7wme_3?m}gNJ)&oPdsri*JQbQwjMA!; zfaN4-O+nV~k(}qq>qz0zcdX?`^w7Iwz~JYqqeSMJQqtYM--=YdpP2 zA0we^EyoK^dc!Ud)VA7O$R>_(g!fi{$GE|}+~lXNeWEJ!<%t$=OAC~3iD>Yw33092 zrR!FAlM*EV3cXfz>nqD1GuO&JIGS@+WHUI~YA>CBgB3fgoibfpziStGGE#IHJv}$L zhsf)}TEg}Fq=Is(W7|@`c$dZeo%xN~$N$BES!K_l(Hk1A>#&pqbdh$-@Pj=dK4B|~ zK^NdyCJ(=9r<7{^U^M}U<8Tk3{gZ$nV9+xocr)DW@AHDlsc3&?Ltsz>~~^%gi>Ok3-4 zwkNv1gJ5s!Zv1tkhtFlYy0!J`Z_+rcnms*SCXFmJ)#~FSJs@u@F&jCr3h6ikmYy>yrd1t# zT8yTOXteSH_1>Mhp=%x!FiOxE=X*qlT$eG+-=&{j*)FuBmSE(+EhitJDN?X=t55>|Jffkv>oZ;Tk*#cnJJzD;VM$7(yJCj=sg+R#VOX zUkgn&XI*69`M)oWN1Z(f+dVDl&gSD=IFXpgE9dw6C0Q8(5|U2)B8K-WjhZb$FWR># zGzGk09>fr&GSCX6CtYY?k#t7lw7l)=r+k~Mu}3qs8b3Z2=I{F7o9f8c+5yivMbO21 zmUE$-2ksq`(#^H~ncct0qk3MSpKchfctMYi2O)(Ib|LC{{s3*7rNW{JA4<3xg{p+m zQZBIaCr<`&9LVYQ>3pQ+=pP$Ie9uuJcHk)gMECOb1U^S@T1G$z?$*7+1LqsYrUY(3 zB3oLi*M+8rI$I`?)NxR+sSZ1Ow2{a74%KZcU2tTR)<(yx?)-&4j+PKw$QoklTIJ+% zTg3WQKYHujM9ftJauKmfDr^8Js1*89_vGI6$lF$;jP1K=`vqR$SlMxj@PXfEYD*<( zZKLzrusM#T*wZA>9#*l)fbJdVtvkr2g!qK}Q=n zflq2{Odj=KaIgeq9u2fUMIgm&C@j$42*Q(V09O}=V8u*>8%|4iOhj0haUTRBp8&8i zI8%?5k3W!&xt|=}qgnqzN~UW1oHh=lIdKkIzaN5PiNwhp2ef(61^;o@P1Yi;nJ5eiugkI_Y_+STD_cu8)RqppAWQnP=)2>N5-Lsx2`9q%1#T%7$*Vgg zDepJ|D+i<8NU9tgj5u?YdgUd`h-e&l(8G>L8Bz&mzd4#<`~zg(NMxgcm3R79%MNeAvwb&$K{j;`0N6H(E{0P6$?enoxh?CJYf_xFHhgQ@)t za|4Xkcc{sFDfWcG6(B6k)38`us<>y2RW~t#kr`b>BaA}{&2c5mvi=e?;`h$|H5If5 z+8xj@Ssq}La|ldMA!=bAjb9|_&XAntD@RBO>>g@bA~KbUU(oJ?8Up6Di8e}7Z%6jLp>|lDn^Y$&$LDP29)*cCg)=il3G)rQAP6PFR7Fm zjviY`FC&!12osHGB}jsoZNZ;^lFTl@U9yG6zq;|ckM+%}4R6uugqRwVy9HdH8n zCvZm38sG0AQhdAhh)vLhIq@hNe>TNs0KEw(eZ@B+%nExK52Bmu?C=@@v|7EK>J_W8V0tp5c~cd`kDJ_R5uw-Ol%X7zAnjTEi!8JV+QF3l<|m*g1$K$NEA2B8TJ&3v=eoRS)^cUG^n4Q?Ql*b+j<}`y;09E!@3TW_kKX>a6iRv5r5_2sj2vJU6b{cvEV#!n)%%CQYc$p7S#uw6vPc91wRXW zU{P-Jci8%bwqY$$q3XWSV~aLqpUnVT8r4C`w2(brRt8i(fN<~$88*1=(?JUR;AEE@ zZs+xh=rmxwR1*`SVdjZTvIKGCiDph+;3{6z(s7F{5`-tz!=dQau=yx5lUZjFDje^m z6=a{5ESJfHH6D8%KIWDim#07Pub$wNZk&jGOxNG|6PzvH57$zK`!eLX8|dC>QPFi2 zp#@UVpVFyMm$Vy6sHC$W%uV>pky&nqPoaj>ezT*xY!6sm$@D|8;E?0DsJ^9aGfJ<) z3_)@Dp)REekD6VW6-cYKTe!UnKt4z(9C`8M3qk8sX7?wx%cI|_^)w7uqyl!m*HR{5 zAS|lY2mvt2P^Um^+C+02jCTnUr&$OmE^|zz4N54PbMN>b#y$wDf>V9$FOo!;IppmvmU$ zg4*SX$pK+pe+To%GsnW=g<~0oH;#)f(wt_bL;k+w`ufeJxTTxTu6$1Oqh+B!7rJkL zm(~Rw=I&%neIzkkVui=J-2%%O=PIY2#e{iHKe1xgQnk3LqC%UGZ$9d9u{~Xe46${l z)Jr-jd81MqJ+2zpVqC0*IgY|K<97v~8whHIuk3VOFZ8YfdxH=sCLvFGVO(}8fpL+F z>ANgSBWx1a4i{eIm~DD$Y(p-dK6z<8F9D)+`nlcx*+al$rdOu8wK?!0NqUFI-gDw= z-Be)o{uTUkTI^ma+@ibe75-0TmFZX|gzQQ*Loj0;Gln}{=FVMUYAxm#G2PQMs#`<> z(Q;DN_{u4w+(1s8p~{*j-#XV#pV!VnL0~ipkbNW!Rswx&k(nTB4|meg@E1&LIl}?= za9byP3~YFX?i9bijGk{Oo;R%H2+=u+SkdBQj^)Z7i7SWr`h4D7=%236)M);T`%i4v zpc)X{$^*dNv?hx|$?M5)wqvEcoQCi-DL^etc_;fayw*9l3oRIgK>@+~2+Yuhm06&i z^-Er+(Wyp(T~gDsnZfAe#sV+;Do-G8!v+0L(V2p=2a}O5j83)S34*%S!_NGuf^;jB zZcNvsN1ySWgxABP!&_S>ZoORw(OI1zI$y^*TGjp-0fx1;f!CHj!2UyL<+7CXp|t88 z6!O?&E-KiL=Rood8BsVSJ}?bNQ}0Kg?-wA|J>Knl-JQC%U*4aKPv<>Ig8Dn%pU6#m zAN9VyUEdiZr(5^_Zr#VLkQfFdSNjNf&wHQy3Y-3Io!#1oF3m?90}u`vLf-@&%dQtf zoUEJZ3WMN$7V-}43obm4@bh8uN+0Ay)5j%zcCH9q$ON2y&F-O>GbubR<8bF+xv8ZM zZ{inLtdk8dY23aD6vN^-&6}s;46|ukUf^?i_C)+z5WdTE^{B3)3cR?@p;>fL`NV|S zuGSltMusIFbo+K5%-BaGlYMx z`2N9#wto!vQ;@j(e?+aSa26d|lVy2dqO=!~cpl3mb%FQoPG9xo(n1D>IQ;kM+6R_zgt$aPfj{!M^-a3b1&SKwg>CwqlLtBOgcC|f_pr6xG3tT63C@wy|{<>Ye zXz3G~%wgsOFOfbu{FP%~+qYpY?g^qKi8E2F=KCXeG@sxT0nMZG>UKGa4au~TL)gQZ zBQ{S2*}*HUK4dDbPG^@dow28P0a(~HCy1?|>P%LSa;uO`Ofk8T4(>w^%ZEarRlsz>r6<|$+%ijMd9L;r#%N?YW4^tK zo>-Y^bv}wZN781|E+Y>QltNT9Zkh&BIeM}E?s#`xf@cnxKEW1e{6ipmB!)vmpDVCV zQ&UTGwi`mSm(ku~FY!olCm+^I2k3|QZ5`ub-SwVB@r1xOdH>EQCIi)n4celWNd7X! zuMrVkfzS$xM4mUDs#0eV7%(#4kS_=aYIL#V%QQm^$dZ~Oj9 zGgOj?;={i==sp_gw!xb%CXQ%2LU5?&###XEGeW+;tAB`ihvZ7OR`)I(2uM{{TV#eS zCiWuHFx&>c&Kw=RP?0>6LV@Y^e7y3_d2YRNq~tS8s1ay?=52sP};R4g9atJnRHR&hIZtUIp|&sy+&eYJZ7y zzbR&f0VX)1`K_{BC{U}hv2Y|?xknIU4*6mf$%@4v8zBi=8DIC0d*_-np8nezKWMXy zyR0({3me^gT~@g9NDmrbZ^z{c*8KooQj>@5(hyjtI`wJ=7-*^pE~EyIZ_4|r7SwX5 z=wH2#sOpo(Sl%}y0U3!r@VcNt4*%-uaYNvQIS3FCF*pzq{r|qm{9jAk^#4+sVQ_SI za0EEJS^->|Rrwt@n2@$W4+ZhE$$|Acpjetu^LaREmQsVHtP&DS6H12h14(AOtdHK^aD~D>H-Po12sJT z-GSGIYOG`|k772P;tbUINpBa3R?4#hK-4DriYwZDhC;+ufwLu7PG21~z-$R>cYzC{o5Q@Ro@#WRP+Bf7B_c0Y7lxO8fDo?TQ=zK|kYSX?85M1+9*45`#eE39xe=P18^J zr%f4A+-8PL9?^G=qotxNt)NBH?pj+mseVOBODjG-OOz6% zGSpXs5+|Op2(I^rp4naEj?U;LI)mc+o{%@5_SiuY` z@(MoOczA|7BxnpzqZ%paJ31>~ECQqtz%kYSm@;9mf2qv#*XfYu&xNC~>4bGyk7!Se zk!MimbJ8KrHq)4`Wq##R(AbZo3L{ZhWo^g^XLC%W^) zH~;(S?pxHfFYbpy5}AGOmpWx&?T+*hdY_dQMEkbi4fVX#TC?(v2#D7=ZTw&OZ-oCk zVM!6eSq%T0s3HHert)7kQfp&(V^0PvduxEHD}#cu9l*?PiWz2*2~J{Jcr@nF%=4M zfLvQ=c}bg75oJQ+j9>VqbEy_w&o8IcpznWmE{0F}rUU^9D2xCIi2UDGphV@Q<&Eu) zEdb68rnbf|E;-s(M!2g^xxhku(7|+3NhFge6F=#aNThTXe1H7HLjsf5A_4*>vXar* zC9els(YX}qgjI3fXM4FCl3vG?-(Zu>Vyn&SkS8Oz-{R<2X_db)uv(2%_G z_=`eB&i!fZ*!wa)mBq>Guh z9N3F|+Y0if(6AZ6)>i{U3epN41GC9+OB2Kkh5)lk?I^X&5Y!2Njr__I z4!%uxYpw%BfaIyPOAmqwjfcTS;;6Q39ApY& z3Ni|=0M(_wYX=e!)uq2X3Em^Jiw|;x=9$*l2~L2{MSYvz=R@V`skhq=Vu;<(r4Yu9 z97Ms_3SY*I-H)9Of1n4ZCl_|t164iX0-^{d2b)b9ie384c#0TqcyZWF0F{wKw*AuA ziXv5k#0bRLXMhD?lYL8k+0sf_#sZy~1)Y)NSmt5vj4WP`_>zV!x@5q)AU&J$=zdL) z#Zb@O8izPLCquf7MP)$*t1W;ym5zl=)`*9@nQ3wtIFx?eS0Ia#X#q*ZW!yEc_rlDC zIfJqI7j}3R)ck;+d&MEHE}0QeZnLqY*?*CgEyV<^&aS#cH zVhQFwUbia^aa!)}qU@b7MQX;=JfP4=*pQ0sfjr7MF|?Q!VW5YAKWj!|cu_wH(@CW{ zeYzCYSTr+s;Niwqq)S^^1EVL-n*zXAm~iyUv8cjUJhJ(;^Cr`y zKitU~hhH5xHf9S~)`)TBkn`BG>*qva2}|p`+lkm!9(8aix8T6zQMof0N+Q{tna71U z_S?{_#M#>{RFOl4TTT7VFnl&HB^~X-sQ#(HV(zLi7-vvC z>J>+&7Z?r2sVDHJ{K}Ut*>(rh4r?k91x^?4L>$#h(p;mIlMQ{~jHbxa<=uf#5f*{I zWy=_0{$roomnaHx|BR{!Mz&as+@t6fsS--HDf3rpo1459cczIt`m&l@h=xUFZK;x? zhL#R?i)~5ahR#~^r5ixr<3eW9IwsEsixllON}~ks7vjCBGP=cZk-U|mISQhi+%=j~i4YEdV0K8diDDRIK6O1pq)1W(m2DTFU2dC#3nDCOiHyJW)U zG)~kff^L4sDV>d0Mz^`p)y*o0Y`&g~x@DyaF9)Td(Uf=jS5@6T9~Z<*jgNc`d!rd&x?leOYY=13`v8%r-ec`-3euIsRHD%k`&|h{%S*YG>KbGHJN32T4D)^l?O*y@~S zfZ8V4qQX=4l1Uo$NxnlGc=t$W)AEy#%vHvU7B6hCJ|Jiz;#I4%W~|MDC;3_3IxLeG2Qwdsi9`NB0WvF2bN0b=UgKX|H`$T?GJy}hDo3L zd8Ouw&$t2Hs!9ZGem%#U(!!3R4K=E%Cfi!8O7_&&t}iI`L^)7-%<4)rv#ce}t#oq@ zBo*!L@MTO3xtb(hn@W8rii$Fxk3<*8fV<1aEz*T4bVL!gTk3gGy?VPQjL`=9_|C} z-H?HNnzO6Jcmr#}Cs$qyUYRbkI{Pz%stWWqU8^_zASd!|w{|&s5Ag?WU2RQ;W!tJ{ zIdug>bvwiQOyskg>&MG@YPz$x z)u-Pp<-_Y&Yuppn5^EZ`DLY&Gi)djKC3>vfOt3p&boM#t)pj91Iv&|QKFK7bJN4EL z?)}?YE!I~qmNm7?#?E*f=H1VYrHfM29j=B^_t3}}1niOwE=yFh75jSb1?5~#)R~(Z zM`~!$HNuz)-I>}gt62=-A@|m!nUx3C+V130v{D{6eX#nS$I(`Ew#8X~SkxBGWAm2$X)Tybe z;?egTLDMgS-)iSgS*KiT`wqp?M7fvgPtA8j#Md^X_qrY~J@T{Yx=PB9F6$U=ZpT(q zBc?;`i`_jYN&Ug_qEa_KH!qA~bJ2CAtgSut zC7(nSZ=FGy&6Ap~w=zqH%fvM!Ixu=(;j`4 zb#X3R9W6Cvmf#G|j5&STubdr|0lW48@Msi}Sw@ZA$7U=1ZA1y-bCY^0)4534HFW5V zzZD@h8c>m0Ugb+^k{4>zOepYJjinG{`%KXB^{X|&U%}m)HaYJ=4&Dv4|V;4{X9*l8;bC zO6c!;#93tjg$PBYFJ!_Qrw zCVQ}WY3}gcm>*NICi_h>n_n9rdlI@ZverGqP;E;pFlQJwpT+u#WwH~M9An_oNFgwKfjm(NiunFWF8^_k@Lp}_L(PIqrg=9=B3 zDSj9cx@2Z(dRdnU+!Ir%Yv`VtPE4t#&;LoMVQrpH=VAS0J~cR%y%yRIHKH`wYS}0$ zNZz@CdG^A}B-1N@u4rKl`I`v>p|~F$RL7O3MkUQ4BrnY6)=ewIVSv;Vz6<9jbafYn zFN&cH<4kRUa@Xw@;K?t5=l})RhYJe1Cm%%Z>9Q;ADQkqjjpK>8jp2#1P2h>KjrN?A#)Gc3ECeDzJcSRdS z%iImB*@1NCMPq$LTsAU~go&%`BOl(4Hy1)L*zCgQ#+lCjK6T;38WhaQW{feku3ys$`T6sIh;RZ7>AFuiARv5fARxNG(YY!BM+awDD|-udS1VhWf5=@e zXd|^{bbdzG@$a`c?N{QUdTx_ICT$2{VG26)Fd>Q{vcPim0CWE&=0;{#VX6{_;q{gE z;q@>E_hq!sN;{~M@~v|HruUwk&Mi(G`PugX3hXfU;(J(&&atcjD-V3%3AY@nKDMU-{uxb>AYa zouO7WU)`A<ZTVsGZ8!oba++AM}8P2SW4@X`T1_V8N=_=(W~v^g~8LSvy*6l(g=&yzm@h`tfH z+Y4Mgqb=1|v$W$4p}qTy{3sUnl&V4zbQd(^TdBgNk?3|1@F0!#U;6n?^aQdc(^}r~ z*w~GD*yy|M&D*(gpP%@4-TYVBWOK`nKKY_TsbekMTYex>U>my6&}yyM*XQ;-y=6sp zy;ZFi-!nbiIrx5{dQ2S-Y>1gXKd^D1pURT=emgb_&5tD3n$Md?pP$g43jJ01VgZ36H3i^VD#|2C+YnxCfD*fV^8 zygY*-9a>s_>$%I`twcl=Bs#mK$&Kpj0#Onbxhkh(!3vgGHG{O)kIt&}DuvD&s(Nvb zt%hjA2&zLX<`&Z=_hqB!25vIAGFP2dUWFWWw_QCwju}sFh);iNR2jdnpC9CbK?(B^ zojpn`KRV1LF^=~ZMVxMB7{w`)fp1@ho32FCd9g7dw8Jd!e4nK&^Xn;QsOaa;pz3c4 zcIgyAw-X%)PV^4i!*75YtKBh%a#b{7p;mKz8n9uNMycAX63zf`m&tH?ZbjW5bE&2S zny5vUo028Nl0`P7mb-nRG^W3>D;+m%wkG{-lC{O`GQ;K)9<+&mwUWS%A?-u*Ys)E` z(!8H-S)s2 z3tg=Sr{2=e3k^`%QKrothf3L`q7)_)u;C>UHku@g0k)Zkz$~5o*s=F*?vqYBoTxF+ z=$@8*XnTvpG*0a#8W$$9T2%)Eo3q2_&OcJYtmEsy&-P&&;zEl$v>1ch-*m$J_Pf?B zAv@_&Fv?%1O~%wrCM-5q*%mj^ok|!upn4fHhb7#R^=&~mOaQswtHb6EPG4}|Qe^yyjVkG%DbpP4Qn*WBj9(O zI@_DBd5Yu;^L&mexBn6~>JPif!+&P_#sLi)QL-HFi?ZAJm@gMh?f7$E1t_@t#gKJZ zvPn^~#Y2DuY`*m?f$~th#oBF*5fV{X^zGMjGe=J;hiJw@;1|Hg4n|RuHZnBxr@nHh zwfxv%pW2jXjmND7?U>vda<|Ilj0;AirVb#NBY@#xPi>u~f=$HYSr6jeZZ+kGD2bu2M&f+_6{R`F)@~$;jH&3mOn?laB;aq5Io?Q8$sEnqj zJWtygoMp2=Ml-nd5n(78GKLM^+N9N}gtB``lvyR5;&p`0fXj0^<12vW6QR z&&DD-^g*@uJ+hd~&H9&f&D_e+e~HqbB)buI>=`)?t35SEzO9K=Wu3H(Ob&>K9Ui6; zcU$(lE(+bqXPwp@_~EIGl%qcNH1Y_!1W+IbPOJnk_ zb-S5D|+q6STvmRZjb@POfD4nx}-^cUGs}^i8-JMzT1x^$^Ez+vLd#T8k~=od}|X)IM$yh$(Iq5m69gnjpHE1Y%GAxy)70M-$MebMl62cDBlZXGq(H!L3f-mBCHf zM3<#h>TL~@@N-;e7Ja1LJ?YOXFd?OBh_qjiVgDVBpZz`;#cw$XZz-AZ0CmE}gO%*w zQ4Pu{MrnWK%X^Y$LVG>T(UtSym#vr&8*j?nBP+ddN5Hchd*h^-nI7e^XTB-2s<|&c z(H4t=ejvVP#AE~WN~km_ba{)z))~`tSt~fn6;m{4nG)f+7D3fm)RH{lfqdPVs_xQ= ztKI@Lt}KGiVi$)@E7{-MAK$rw-qjW+xIW+jF6kf)%1LAPr+w9O;xv1O;1)*!^85~` z3UBOYhDY8-9z3z)vE28 zOT($d1m)sG{KTnhxt#bX11Y^K0?)0_-(>Bu1_p#$u`kOapZL%GQ zp*|b=mhF)yH_p&MBc?l(GP!2>fIoWJz;qDoV^n#MJ(IHjj!RH;q`-T04}(>}V_k)( zjNZ$!RUd!!62^(%QUBi%-9(e6gEX{u`Tl6fn+4zlDuMaK;trQlIEzeJroQ!Tf$52M=u@XFt_N#?q>I3TsQ6bHFMy$YB|OQZ zVJ>dd3EbgwPx0z-Ze|DV1yg}h_zUZT)4G-#n}-3Y24=hIN9^gerz}NvUXjk5Lz*ro zp=3sD&mNk4TY8nh!zZ=t0|XCjUfL(|t`X|#U8l{aMMIy>MZmb+9=}!&*H#z67!`dPw`KfsME`7D1t@JrdHh}` zFIaVH?hD_J^iZB;=B?8^nl%EBe`DjnwPC+Q`D~ppvSX~DE|PjA!LV+AnH6jM zq;iFVd7*b!zh>RV*e#JCQ@!&_`)J(OY_!$ z=ZCcUg4MQxg=Yod$odyrt?4R{?M?;`htdq_W2b_lMZwl0QoQ_Hk$c#VFnp2g44(Pf zR_NxETOf{PdrR=IZAGb)?aw6vneo-Tt3xSnbKW(6anq>HXF?^NKX7{P@xiEhkl&#H zDx*d&TvBntfPh3G|KG16?QV8WLFvvYlO) z30V+W7F9EuJh`O}O>xDL(Sn-3k!%ZbADyiE0w=!VC#cE}o}@%sP6J|6Kh9OBID zVaQF-Q$Mza@10~*ZYPq>SS3@o&rR!z?@Q-N_N4#AiNy<$oY0dIkP~znzatUD0XO0w zrx8%>NCG(%nE~xMIhRAcJpNhvq%7<>@^)#b2M|ui`}_wKhTA)GXi*e%ay>Jovd1WU z1y-)X!Du*fM0@GW@^xs)qIGClUe^uaRT)PYymKa> z&~UWlcQ5TtCeILde3Ooz0hJs!K4&m)b}Vj6>uiE@D{8Pd*v;l) z(w-UC@~NcaYu1BQmM3miMDGi{BN=FXQAGG}dkoTpN}O*R#kNYqIN0DWZDQFl$4(i> zyM}QkyXa=zJHf%4UP~m-cs}y|C_mBl`e8UV(YxaCO6syC`f)vzjc>nkO$~2LKHO@A z59K(dloY{D4cY z0*gF@B{<{uJb8aJBL=M))pk14*$rlxXC$`I`#AMudw}Z!@A>%(;5f!oidpEvMEMth zuVN@j^oDby*a>e29SU7D9G2uu&2DbonuWHZCA2s;Uu`#r*($k03}c`b{1$N#DLut{ zxfPEbnC$PN_*2+(K>r%-3>$y=)xQ;r0zGlXJ(& zSlpo|;l68;F5r!NoftY7D!Bgv^2y6}*p~)H7MgzxO)goV^uj?7^_a{Ig($*?J0Km( z97UyI45x}UD(=l~=7>Yf6~Zo3$pwij-4zDwnU>oliTMGlHxl8hD=31|S|7uE_({FB zRF^Q?I`ob&^Gd+uFNFP~JQ&Y(%gT`snx(O)QO;#Ez@Q1(wkZWt>$5QQ#f(UlYtDo@!hb zC=if0^xu7tU~8oUaB>5<{3E-hre3I^N~4W_qY{Y@1nQyPkT6t98(}lncLY~s&AD+Z z6T{H@uNg0dn^R_RVW#>)8xA4rkn5DFzXJ&@t>j)qlg+qNm(rZLzGUy5xpaId`+nUV z^a9lykwznL&KO~NxPJT;*JNv_ow^zLAeNJsBrg^(^8jE0}e^aH~?Lzk^t0Qg-gnv|^|CiO$%M+_;tB z*fVdy7gt(wr`s{~;4iB*mSJhp1?Xy=X30l%!-0z-Gm3>eV7wGX;ujD1THTOeGxIuj z!Dj6eBj zpUOXj<}3)vtyvg%V=yF&(2V==8@m~39z8w+mw8Ry;`w1S6uB8aa+S8cXK*Nd#%(9| zIi`N4Gv3H+l7_RCo_K{o!s6H;p{3pOpQK^FXcue2M+^ZrVK1_#d@SvF(yu2`OMU@=NG;tua+n&Fhh8dRB1T;4*YOAQn7D>LkaAXlcL z$h8!uPMAuRm%PG*Ck+>8cL`QC5@tS2q(t@GKf<%?#CTZR49}DnkjMkjP!}7zeWkf0 z2WX+i0ak8qifXKex%IsWoJbxx8;wfW1W=FVDcD+v-RN2c4an8ca;l6k-2O~5|`0PGu&@#vMKI|B5F50O) z&uZgKT#!;(JKDXk(l$r0)FsajY>4PMQ3t7$vy>VNd{}mFx!x`zLca?1ABgHC{BGp@ z=;Zv%1_t{|L5;l+3CiyEHxV*|~tSYV{S< zDcgrre~`&$rpjA8lda3nd*YZ^aqSH^<__?lIy`gAP7dp`6d;2)p;)&`fs+}NBJ3y+ zq*dILZQ@4A%6NwBNDX{Cd5S}S$5g?15+T%4@7cVH0~31VhvZT1UC4McA$*sFo}@U^ zAh442DRxK=@ZaUOrrrjlD2y6wLVrhP!L%_VK+1R~reO9*qvep~Ap;b9MwQMDC`J->HM3cyLEdc*1DUvA$Vt;`3Q-PSbRlCxZB;=1*6Z&51iP^7$7hpKOy4_s$xuDMX68S_gVmiB40I3u}Z0qo)B zI4AOoYq18J8OSun!EyhKk#`ENgn_y?yF0dRCmq|iZJgM)ZQJSCww;{Vwrx9^cjlX! zs(&v2n%jN3>Z#h#uG+P}e2Ot_qy+|}sXXiPdCkn67v&%YxMQMXX4wN38FYv%C4I-l z0^3RI^uHnHZo!JTW4T&1qHfzh$hiL=GhIqUB3x$@Gqss| z&`IR>^ZhqGqOw$1X9_456{7)x%jMi`79~F{xgSdV@h8B$C6Rlw#>}^=k?Ek-T_I=P zjHnCmL<&U`!|WIFx5#B(`H)9gRkL1DG0oE9$m));M|dG&sZ$YV9$>b+I)f0x*j783z!zosO+Ify& zU#5=Xu?KcAc)Ux{bN%xd!*X(V3OyAAGcxj(7_FG)4uoXUGp=TgElGyDLz`0P>43#54MV7Kn=Jv_1Oifm~w;U+nYCoRl7}Nc@#+@ zC{y=M9a7{!40ivOMCJ&+VqQHT(;Hi9q9Oo6mAmu5viOl26iD;?*RO@&|C@4^|CdEk zcME4xcOw(~|LZ6Ef4EeTl?Gu%^jWC+I9j%>R7L6!3e%e7byw+1Mu)D%D1LE%(&O(I|7LEI8Mn5RBO!<}- z%OO<=(+5yi-%AIo-r%}$(nuXiSa|SaJsZ1HdqOd%P{xSPqh&C?B{tm$V53OUK3h*2 za*nH3KnaRlWw4?!;!D%zidZZo3`-1wV8IWooHNL&xSJ?2D~9zho`C+4=NQ*pQ!^Jl zZn=8Wmk|30UHzi2!@ER`{V|X!!wzFW>LB>mk8*jq{^HNE?*o|Mr6Jql_lUsj#NrpS zL3jP?y@R&A?9RKL)cnntYgHBU^=ra6*o@yGrG32s=l6IYE|$8Xt53~_eu}}H=c)+Q z_5a6HVXG0U=~RCG;_vz2^aK4r(f?1_UEL7gDNAo0-`P(+cDCEWuzz$+HIRjbRxJfU zg;t@`>l7JC+3kSLF=D}ewHZ>4lku*+qfoE8gWt{Y(p-NgO`ehf(&<06iE|FL}+S>M0rXHHxq+ z|GDAuE_&TY<=5C3m;MwvSeJi;pt)-#TbF^tZ_{N$h)&u}9spr3YAPzIHIPc`NhM1< zz32xrttGcW94{C$bXPHjm_C=0DVNK!L(j`($nC(!O(t*g)`^&EHbD4zDa}%AdJgX} z#&^s5Vh<$v@HEt3igR|$tnDO&@a&Sruf3*#P+^Mn>m#Vlorcc3QO0~wTJpl4kT_9d z#!?eI(Q*dv9_>w<@PU!YYVHQWahOixhcI$x8XB2181dTI;ELDZsW1cpp9`qsN`@Fg zA2gt$c^wO~4--bl#*%rqla&+q3^`dP<&s3l96M-AR$+$-ITsQeX*f4XPDa~Pv&HdJ zG#VBYA86ZuAxZz!A7heE)ppD$!_aiBr%KasEGJ9z*d@>0awzXsVc&+lsS9omr-wzw+2Ukl34llah)lzEf%LA5`92Y4N)@e^+b0`T`Q`CH>x0 zdV4oP`%n$qRs=bLUD2L->8%=~C$Uw*o|?>0yq`^Z`#1mr3V}blm12VXFsEeGcC3@q zlO60u;npjvw&P>!#;2k5=Q47u*1ddik>7J2X+-)9GV5Cu6`Qj>gBaA z`b+S!zq0R@0m>13>St=p zG54X@y_fX2{un{Ty5Ifi*ZnV(Z<(BCq*^beBxv(?F9Wwo%}5f1@GpF_WSKxLDaFaU zIqQ#jNSz)w7dU^A=mGiVI2IVpcI0YTrf1}Qy>QEifmZI7g zbmHzSw(*z5pIBA-rJr8vq^Qb|eo32XTjq(wDFr!XEh6gJva)16sff=F{LpK{DRY)! zUmFPOK&D(6ltzkEIf*okE5C7&u+FQ1;kW3;2(hRY(y{`TjHtM#l@4fG16-TaierJb zTtJl(tqO*WoJw*fhKO@K@m+F~AjJ`{RXfs_48!vB)J(CyC>qurpsIB_R!L?A+9D0K zskUWo*jDi|@~TJb-+VhNM`6|-C78Nk%sph6z~XTlRon8Aa0tr;aauKL9?Nnqv3^JC zYC=qk%yUxgQ7Ne^rlqk(gOGAH?Fy!hCuP;tdk>XnEn&nJn1epQVWS=E2 zX)qr9wB$wUm|{y>v?6mnL9UcQPvsDvOGT|gaD)x%^v5#GBK_`Swplk4S+}HOxx%5d zF&gchgsN#3Ga|=|Mk-hMm^&Tl>Bhykl6C8Hn8dXxWVZ`Z7osCTauuB#hSoWuu#z_KrLc^VJqZ~5 zT#;SNq8+VERIzRI;*Cu6)F7WYO&_pzF3+xX7hZYm%m9GGN>P5L;)((0rfiP@)?2!( z2kok0PXP9!eESOwL8&e&kYC{z5v-HaykL)2yCMX+daO%jPnf3|SuM|8o}oi^f9cE=l#SK3jN9ZSFo1Z+y z7aRJB3g#8K$_jc2clWwZi3F>lR>85VEV9wmK(f4JK2mG4*zH{=zAa!(QJ1thMMk05 zWb$>w@;^)DG69;cxi>Eh96bhNcOtImDSV>O!5{mtsIfBsZz{*C1lM#KbbRGT=$zDDY68 zm{6xp@32RgLuHPXo~V~Dl{!;7XRkJPu-L4_bfyQi!BVKO_-%hSq?6sL%qP-9Ekjgb z9!|k5*HV?is=Y0%v4ldO|LKW&onvKFh*1z!EMk)*UnpmwZ!?Xl?I|i~`NIz@Mhc4D zC)KtM=8%FUCPt~idyPurCMIekT<41tw2d81N0pAJ9!i^Nq&1r=R>|c7y4bp{zM-Jk zYSF>3qCTh4o@$9-ZKbxTs^5@T^2ZAG)H1(A7VLW+9N=RknwQrmEDV~a6_f-;Q-+}S zE|gCgh`ofAT%%OiF-K5VV39i1EPyGcZZunIw15mngvx zmI4Fi9Qr_}{>%=2T3TDdQFTp38wG|fb=^5kbIKQ0Ag#m9xV}xZpRAD&m@H9)y~NlS zF7iM*n0zpkRNVxJcY?lHtO~${Pm;U4;d4ToIweR@1@bP6!-G>Q~)s zzyy-O?9KQ$PBdJ+3H)0NU|}?63HTa_T>70W_AwsWw;$=rU%Vx=R<|5S%|>`f$(o7^ z_PJ^zIK7A1fiD5K|0@WelbWlhj;^*0AZ*Pp$S7B_jWNJ$)@RC`o(ef+00$8OnTQ$-f;wgpl5WL zyQTzb(>1%sYA5_%Wr5??31iN9bFF|EjR;ClCQmUP?57l%y_N@ZQI>%AIWFDq2d8NSq0~>mX>*(5a z2>UV3&+!Z&k@Ue4=}`ZaaI=`lvO_ zc#OM2$0}eI3S0P_G0uHpHu$t&z>j!|Jo8*z+5600N9GRXns=_fm)O7XV*Q>bc58p_ z!DwXB#zk~g{is%aTJ@yTPN0fm3)eUmd%a3OW+r(cnfw{oBJz|f-d54Wa?wh)Gjthx zj>h!kzC+2(edU-e&;{)%kHfX-K@T;&qw%$uzU zia$-s%0$viR9kf^a}o#J{^eTq!M02k_NXd5>{20CjQhJZZNNz z@|+xn8z-rf%T;H=*1#o~35g@9KH^1s1!j;c)-KrISXERQEa-A5o7{Q`i8<4WA(JyZ zhgAOnp?Xlv>A02;OthDL;6tW)CmA8#ks?u>P(u+7f*`GDZ`R!FwL_NM$JAY1GXOfa zav_@2x)Ll)yNnhbXy`?d79Ce{>cZ%|Jv%;JIXw{3+3rYR454moz=nN=p*anos&0l7_S4j9nWJf1p z<`lQoFpAMulj#2bP0KNPBqo7#aSj9`a5teg+UKxPr{!jz`8O$4|LX*ft7A8F`7=%a=u=n(CPI=1G$)&9Uk0^hXV7(s# zZ_Zt;a8e_vM(Qb$XoQh58ZUcXu^3qx66XAu9eLFRo+BQGdh*K=G(b@q$&zrE_)vJ* z9BAO#f{Px|)&9HPp$zv(tGhSAnRO$eQ(&e~#ir!c4BOvI@um_c^fMOEjw=u;%peq7 zv9!1gw4{#ST1PZy-m$c!P+RPCum1UBp!umE&bTm%V15aaAr7L>;V;KSz#s#%>%1E!KGKzMF_<|lUIGH9c{3KD4es_S8=+Cdh^Md z>F8~%R7+^#eRKCl2vayH&$80v8?6An?t ztNbfr%80B)O%Z5M5op$jU>e5)EN~{{ze~6>`hftZIXXitiireNQ~x${US#ealz&{# zYaX%GJ-X3ON=uEc z`-nM>oN;8dypF=c+N{f+(w+2*EOpNMu?Cog-y`#)Q~+7fY8b&7oMU^8kw`!U28c zkK5->QrzLBILOlFvI@}x112d+BgslViA4#8z&>Qvy}pr8v7KQTF+*2jtgx@8F4|MM zaF8%<^SGw}DMQB+Cxl+ls1)6K#mX@Q++tLR`8FQC3 zQQc8>g*_|6W=frEeS^;TBK_rrDjA1ik;`~0JbcH{tZRlc*Nh?aujZ71GX1863?ONe zQFi%gw!F>b2cqo!20d|kQFH(OdL)RKW@-d(R#?|1(KM26YMFW zDLAygaq+@zpvH|juBfy1;?;nH5Yj)zre*bZc(f3(e*a!%GEwOEb0c_XB_zTDz1=EK z+NRzXA2m-<)^&Pc3P_dB9zG&@Q2}jHxE`>6>@dILi@_Ks73o58s0=tOJb3}wPL?I~ z1qRu{0o!`P;*!p@9@ZzmolncEv+&MwS?NzWtFgnsf>KW?ULy{sN2DBrMF(t~vr^p~ zba?dP4!~5mDRlzTEAs<6M@ew(Q4xF4(bgPDT32%vIt5wl9bRORz8vB)MD0dx4cVx} zRZkN1u&t#tuJZPZEHi9LNXkQDqbUO22PCNFvImRN^+@c2lP7o+4HqPi?gYh7HdU{4 zVHa+*x7$H74N}qMGfH?C0=i*ehs5r>G>alGmrEm+={+~aHB3v$WkTUdPU8v5OKbBR z=#r&Vy@=EGU1|$A6C+6sBHZgK_=VfN0R=_LF``1T7@^{FlsiODKLX#n4O(xKz&dgR zkQ03W5hM?IpORpMXi{T+hF!!JB#wZ(jCXjFg(;BuuCLgHS!UzlE%a|L` zMZ*F1$kvY$=SlViD{104uk{`(Y@$o(b(2#S98NxT(s%Q*)e%&q;yXSJDa;EDR2J=~?Lx(o6QtX*tgy2oiCgv>GQbVl5aZ(y>Q5i!hZ8T} zB{bV(1B|B;MP+l@_^u7?pS7gZqpt!b3JJTi@5B#B>6~U8PC)e~&lMmsw=KfIY!yHKN z>TWR$9HSVArq=KS*Q#epkG2VYoP!vsJ7TI3fous&eoWN=&=%qE*lxf5~V4N zGTIzWYy%uopz{VL+k5&s_eQ$GWK)bL&|2BY4#x>rXC_~lD^q-`7{v=#HcdliEEdm! zjWba39MyCK$Ws^`sI-x82dh8pr%210-hdOhw*G~=5_?Xc_r%@b2bGM(X}e##w(q@d z{2=~@4=&zpcWr68W-MR^f!7?}my82rV}#VNC9`$x`t`cOmWnBDW0X<9$)<)$u@003 zN^NL}=E;$-*D|P$I1R>%@3bgdsI1-7kp8OIq+x&?in26{v8ZZ>>vf2n>OJ0R>$gOtTdp~{rz@tHxg?$$jCBXaOp|15DSf(3e9u)U6vuqCj90(mM!mq&0rBJHa zDd5c}*_v0?4!=QIiD#ZuXxox6ld!8S9w5>YgZ|^%A`qISV8aqxudp7ialQ(&*1`5` z-eI&u5^xnI^e4=5n!K#o4b|ehhl?o+!fE2el%cBmGKsf7Fx(f#x?T#uMEp~Bhi01V zTVkUlL{>rPuZ4{4AE5Nbbl})whFc?z8Hs9%-P;fYz)@cX+C@{>i>BDQkRXq$E<(CJ zTM~C#l>wVMY&-IWt(dTfVXC3-cs+>7QsUGWQZX(X6bjX9tv#q%nJe*(CQ{Rs=lj;c z%kx1R$=#s`K4ToJX@Lg*Td{S+cEhwSZ7G4(`(kNU&R4t85i?W-lC6Jb4!Abjw%hvI zS}?Vt7HpehvZAwW=5&qMfOaw3)(2`T+^_1Nek}~a5mL{BbWEf@Mg};&%qW8R=rX~=^3D$`_dYg!7T0wkL3Eh4QQDj_ z&XgF8&75$J7KR@^q(h`BVueTyF;|=;MQ65S4icgH-LD`E2!qQj{bWLPu~lyx(!wS8 zRrD7a+%ww)qz(7QRU>RKn*+vqWgx*En9GLyru)G0#2Ylm7W~C}lnsvskLZb&C%=sF zDsTbFx2V3!t){5G!1j+3+vY&?z+>?a8DQA@Ce;(!UoY;hzI9CT0IkhK>ALbTI)@%kZP^g=(x1LS?WbRZ|>oN0Jp45yWbk4ID0Q+yQV5R3TC2;4ooa{ znLOi64uP5eQ!fu7VWcUHB4qR#K!A0EZI=uX!uEn1IB`uAcUuC-#B)&Fa>qUwBY5_6 zWdq+NJCNwDWyG3Or!u@r0##XGlO0Eu@A19GrpKzs9J69`KmgQH#;c2Am$)2Br%gyw z+;CrTr}lnwEGmg=jd8O+$OU%7cG3AJS}z$AYiIdWV$PAyO#jo>#xk!GqLL51=RNRQ zc6R|C_m)WVVMb(*lD>VDW|)n*?1ijsAiPhaEZ-m+Tqa0=3f|S%>Z8|SD5;Zw>W+u z8X2l#b-3z^63uws@YTEqXXUeYecCV>G(iraga;b4h#^77+s$cepBFeTbk)%>u(aDi z>*y$Fj+2j&Wv-Q&U{A6oNz`H``2#`__6Bqsw>;c1A2yBV*Ij!4I$9;GEUuM6Buw?u zCCP4}GY?IQ%(L&-KC9YRh-k9Y<3=$Imt|U(q?Z?g=FfAu86cKkFGwqHg+pgAvotnW zWZ+dTziC-O9}&48udpw3xw<`r`weR8dcJ3@5y`03h^8c*d_Z0o!;+^BtJ%WNA&)GP zXHA}Hm~{ZE=S(`K8o-;A1&3i5eXQa`8%bJgBxiJD)a)lm8^#JMVG7*I%=7gHRzKBGPWM~~Uzl}u z?_hH&a)+AcRc3=P+E89NQSks`vw>@R%#gkfhDFe$*4RWIud&HoH}E;Z7WUAIIr%`N zBV8%`fn5b>J+2oMtaLF!ZkvMV7?;(EB0N#ZJJMo200)QW$y1UMRT9NHzy{3pXp;~Y z#@De#z^bCgiq@5Yt(aDiFhw6&z`75}F1Df#`B^!hw4 zsE9$BY%g-_?Nnrgo=$>7dx(^c%Zxey_C_tKIYMNURX91d#V)MWzrM zgg1G!q&_S8RSva=vpioA5_Vljv`F}X)85A>PY4AN z6XZ;xE7DJBUu8>6m$q@jLZd0w2UF#n6ENnEVENTZr%~8!?nEZ2XY$WF3k?Xmp(7is zuLrQnN;&@Xo&ckkVJXu(^*8X6IU-OJ0S%2+_1$op3*c*{J31#gWofw}YnGTrcKEki zlFQ5`-qy5)^Dm4p7;d>dz{UwKQ}b90J1;lX6Z(onTVi%h@)~#Ky~5fFPtZ*CKcR+Q z-S>0|vRTHYYSE;&?fYCR!D^b~dQjP@65rDgodjPH>ARSMD`}r&W6$`{_~0E%E&kbN znWdL9a#S=fkSZ0NM>NwF!)c3QwYTr5)V5IRR>BgNMV z8RRaU453kz|I=_$x{kd3`~zEhnCmisi$?vCoynQ;2b*U8Ri4k11)m1%Gckfl&?t$Dj1n)A|5`(oMTr&Z=beD;eO9&wK z`5O>jkL-pju3Tu9sasY)d;}PA3fMCxg^B%4hL5 zrMNbrf$h;I7DCGT&Q?VB-o%-`Bt^#wY1e6~Je6*;{6?~X85uU& zSIvsL@=Beg)8b>B0atH3`z%|!y!1TvdsJTA&Ii5gIqE{7hZAxwl4`@|j>7yF{yuuY z!mD~Z)D0_bNvEhB>(>XCU(iFIu+rf>L(qXE7oUOSY-RV{#pgRY{T47<50C5b90PK- zQ*ID`J5DTG+$YiRE;Oj;lB5-g`BQKuQJcEuxQZC32r^nT_fHoE5&bGwmu6SUHg;V@ zr|jHj@-V|v51CT-B6!Zb{wrV9RQCb4V_b@H{`-7Sf>T?OP3QMw%|-cIIqu zPquOkWsm@itjDW*e>Nl=85z4iTOj@NpKtXp1C)^n zC!SFE{HDflt)vG;J&yPi;3COUQ+gUxAF8i&M@;-LS%72f_X1Z8n}enFSLt@7KnMEB zg})a&Tc;ODk6jUybB@gUePa0WIrft#({b~78Sy#aJ2XB2M#)39AhY zGoWglOW%bT&WZ>d&eM^4;Ub1~{)EamxHt2?la%NB^K{&IK?FI7&&U3*)UP9S%@bX% z$cC(KnNJHp?_|S9v!^_4qm!o$ts7U!d_QN+jvYDBwZV0Rl}ZxgnO$Mn4-qR0#_yJ( zjEl1eGpwo!SuYGBPx_#4x98dxuy;H&ArE6_4+ijNU^v4^cH@=zQx!mn!pB*okfW!y?DX@wII*(YOxq0`HksVGici%OA z-s**McfA;$CIfYslH%N-b+44XUrI7_>%Ctnp4Nc1}{&`p;z7_-oP)Wt7SjrZIvi|FD$wT{zxF6O^e(uS}6f|7RK z;KIIU5d?FR+^ce`)+0S~wvZS4l$ymvzwt1JD}H7aE)j!su9=Eg)dhe@xJYGH3Wndy z+$V&%)U>Fn+X*9o#mWD9?T2YViHW6iih7$6eFcvj%sZFHSFnv?<2B|VX{2`dHk1-G#fsoZyx3%{|TZt-%xS^QMAviFkM(&5W6Wq zLW-CV!R|=1%Y3S?cI5{kKT{Vf@%a6W@9|MVI2SiQ_yRfD`V$%q=$`Kdb1SL%nhN5| zv6(cEz1BF}E%7l%mt2=W!B@w<4^!f3DMT=YZx>&KsxE-M`uVw~-n^wp-@4oFQNb77 z$#L49#!r#7s;Y)kd#ikU$eGRrzOozbXwUPbI5$;@<}ALF$rB~4&D|01F|2d{Rkzks z1#enl0RzMTiv0z}ETSe{o9&)6`xIz5Rpej z-AdF}X6+iS+_b!+;LnLN*sJBZU_0f3XF2VJC)Yt^tri+p1`*dAT2x(Vf9ygojLa>_ z%*|)hwAxLOc&jmOasJQW{WE`FKj{?DD-03>B_t_%WNChVFzR5C_!@G&s~@gS;lj4e29T ziI-nd5;NK6-<=;T!Mz^UqM)9NtZUfh_H@f5zP9jHq2<(5O zN3&y5GO50Avbhxr8)Hvp2|pVAj!uxo*E+rZqBn5@=-?NDWifMe3i`_JMrR`UR)|*K zaCnr21>){G!c(z!^o!gV*lc!B%o~SA6$ot0iUZ4VTcw`s9v$!{zGLyeoWO@e`XiEJk{ZZ=$$s zSCUVo5b!&~6?Lz=hF!x^{4qtFv_H$?yT=oilQp~Go=x|8oeOuoIYBiJ11D}mkCsxK3;c&TIcGdfEZv32KBQR^GYhG1?sKMc zG`FiG#<4|Fj|w9XoOWeSXPfQxUkuzWE))r+>7#zi_z#o-E)S`V?yTepk4EmU5)rw5 z(6kw~AAn(BKU>)WD`)EkU2mq7h%Sl`-TAEq+FLGnj}IDJ$koi-yOHErzb!J^hp@ws z4wNHWgGkb8L!+-Jv;nDa38$xy6n1HiWJQjVTPMPP@P6*r;_EdDz`g2kMmhWHTY?@- z8hohq-{s*v^7c(`CF!{Mhjra()_omFVraSoGK60G-FI6m>Mqf1Jo*7ub!k$vCi#<& z9mmo^&^U`Tafb`xo;Bl%Axc4$m}WR%E=EFL_QcUhWw0%4A&$uhi14V9ZxU(K?pitp zK^-s8Qep1k4(yo_BlvtX&_L&e$wG)5a^!#AGZM}TMDOxUL#N5j7hg~PTApddmsSD; zz|GRB7U_{^Yw6&h(|b-&ZvQ@L=XSQcShRAd`X4{j9~orm!vk6oH*ye@zFD6&ffFt} zFmJ?Px|3rMotHTCULD!LJ~iVjKZh0Zz#;848~~&2Uf&RKxerk*8!YlYvQ*Go29R%H z;vQ@2AG>;$;77dYcNA}M2n~62qc5x&iT(7%RZ!D9BMqjkQKePX)bU77_84Jy0d`z* zX#TX^FqSo(*yEFjDScwbr(+Dl(z^PUfDRU{5tKuW`=~y{udR9K%MmJBl1XS~Mj#|b zMy&2+1ckySvM-eZ4Uldy9dtPI^$1gW*C6SwmcewF%ljzW|7V@d*i1%!H$9sv`ff*m z?PazaZcROLtd?cZI0;~KUupE+3p`x;^9d>J2iikGYC`%2dm!tJH<-v~>_U~(y67U~ z%bWUJ%)mg$EBvXe{^B@C@s+~(&X6rr|vbtw% z%3-W|U_L6YXg>qAV|WB?DPdY7i4D0~6 z;#-)(H!#}NWXwz2`(#);)+l_)h;+PKn7=(VpSZh5S4N9=jCzlMe(e(;7}6M*?p1RS>?F-d4_VH_^V&8&Zr-n-jsv_9 zwvgg7kSQ^9Nzyq z2$XqZlBuO%pmv;TB>vPcFsUUlN8EErN(F~4%i3#WV-#)teyFgn2u;l)xu1evP?XAc z+A?qfIt5nr)_+T(*_!>eF77;(cmhNv)~KSNUd-^7B4mqUf(e|eqVbo&+Q??x5b2E(G7Cf)`A<+1UUATKX76O-xV;8~!q*2lEI^geX zu#0$x#*x&w=i;kBs{oUBoV6**qght`RQ7MMOB#;MoFFG2gf*b4NP^QYiz}l}KV5*; zTCqJ$Cob7nb6waM_*%azeqsK41B)i3@=9r50O2Om-g<3MOQXzq1^o}Vk~ z_#I1|{rw$Ili2Tx>twuE% zwnJ+?)+xtwc}$Zh12Jaoe6l?~bnu6L+I84(YYOOqF#E8~yl`IFhgA}ZO)o>4s9_{z z-OH+^f33eA`}8Lw^Eu?~VmcB%=~{|>5f#}8)of@)e|JSdTF!uykz;C#rLKeXb~8<2 z2CX-(SO+eoTC>F~eCMnzMba%1$5{m~Y$zXaq+u_VwDw_%B$~1HYibitQ4booZ=h0$=&Gz?}LQg#64yGj!wlOsq62ZO`U~MRib1$p8r2VDMr00{LfZ*AMgR zlktVpV|>&9a_RFL;gk1LhOHV-L}>{5AxjxCG#yIhO;7Q0Wijbw2LU=B zG2;^Bn5jR0`GopLH8dvMoXi!AjL(E0MRs+3Hh?z}BwMu!Cochhhduqww3YqvK7M1F zP?0f6HCMH1iBQcb4S&U3-Jke^f>?xTDbTg7%0Jb9A;HPzx&6}}T8{&j80_^67W*y^ z|LolLmdfr$V={sqNZt^P)U8{iy(pRRb}$KPr?u~=+m$etn88R@n4+D<;m3$jYXhw( zwWH8khfZ@?ttoyurX3ZoUkp#ytC2Wsi&Cg#N;-%2&n;C z<%Xu)*Z?F25H`SzmO(76l`yMK#G3lyY9i;DBP?|eumk26u7s{=oSf0!Eqi4Voz3V? z?8X(-&t-#+Df_6wza@LoTWe;U>!7`ZYbb~5k1FctXOCa5%zqo8+?l&QYHhh7Qrap^t6D7? zx}a|D-ls~K!5gmt34`2z`)AI-IRN6DH)xCh+@ilH#PS($v5`Qb{u7F=@#~g)+5iT_ zo;$5B4W}+n`nF?{O= z#j`K~4~U4@0|X18+i+&EX%njAa3M4e1mQBdBC9qH5MY`g%C49ooHblA5E`j_*Do|l zVkkGEP5nMB{BUuVhH0|>O?@CWR1+PhZP5BF=fM?*M=3Gw&Yb#^Xx=KI8!N7P-~iWI zOzXe-9JG9B)IZCRQf{jCl}J~i{Q@)Xx%5+waIYfOzQFM-j;zK4v|(1PFv_($0b>=!^px@&Fk+>tdRlJk#EpyKy|TA^U}e}&)QGB zbwx#d!R!0ULpNLQXN8;Y7%tjqu@)&#MpYK?| z+Lk`6EAOf<=ne+}EP0721LIUNOCI|d9-L%Nzgl^^a@ee%AGl}qD%_7o>YW%&*BYoD z>)=M`uFKys_d=*`qKk5j;sN}gx(jJ;uy4)C&M({iNxTH{%xkZyTi^Wg;&YETy(L%z zRP4?@VPmr&M*;6c(a;||kq3FLJ!SZ^U!US(Kf_fsT6<3LA>?mpy7~ZAt-ZyxWGUh= zf0fX(UV8fdn~w^HHLHY?n{KsNg8dNo2xI_P#FY*GRcLLR2V7O+BJ2*Tr|V$rL>GBx z@D43X=iY}&yPiDrr@}TYf8q|JOIvR0ZXja#m#lqXR*5;(f8&i9h10Keatjxasze&+q8AW~bOjGh2+Q#_U?y(G-@(2%n zBgsyUds|a_D^sdP0~G0Dd?hALb~{IEX%r4|nWCiN2y$jf*#gPL!&ZWtFil_T3`7#Ec=@2vITovXj_W|mVL-0B0kI4KVr z$=O~R*^Du8&ShiI?GXkghI*CbIY4H!AQT5Hf^ca#;pWyyaQjq0KQO{Cu#M1l+fU}7n*cC1HgNn1PwdW ztXJAg*l%uE{N5Pdi5vaahbwD{-YDLo8`HQ4uT|;KmrFcf`j6-v{f{>voqU&lQ7;Mz zm$pI==G<{@52&3fd6DWa@MgY(1{?F$-e8g+2tSbOCML`hBPtPPgYm(1VGrR~o^SHl zjDyMhH|;VI=18 zKmU5t)fw#9uus6QLHDXs(RrLbD0e*Bca~pt%c$@zq&S?KWaQ!03TE>r%7iiLqlP> zZ3opFenjmNW=I`c;x<_9#^$YQ%RI5PXzM8}d!@%Lvu_HKNh+t$l})%}1)TdsHi#;K zuVlG8Acm^dPST~uJTW*bT*ZzpO_RHD2dPF-t{o@hntCXjB*9uAh|X3qn>2w)_{6t< z;gQF{NuJS#F?T|o3Vh$|crpSxy+}+{`4VI2~YG3`18$#JMj}~ z{PcHnzqX$T_4m;y0p-WGzv}1z!Pq+m=>l}ig5AA$+qP}HzqW1Lwr$(CZQHhO+urk^ zJBT?Gac;~*Rn&UTl`EoFK4i+2pV|q)`hiPaA-}T{jlO&{w}<%wcfG6Kqx{2?xYkMz z*&EvW7JG-F4Xyi_i-zR?HK?aCXxzoP3wt2Mz^AJY$9!SC{aO3QW?8_f6yJNiYlh51 zPl)$0C{>CYa#iPtdCAF*a> zkk}e1rm6GvXTW0Axmg+0e`uj?tTVFA@@jZXU;rC!ikJrv9i(~l3Vhwljt*u-YzcA9 zaYf1h9skc36iB+5A2%LcP{@sPpnfV(A3u$Uc6YbN|RY4Y@cTUZCq+7dK%d)=0*hsm4+lnLBrRP?{}-$4|HB>y$fi zivU#^`qn$rVgMk7Z)o^Zp{um^LRHvhAyZu*A+xvpTBz1qfB1SsO?1;oL>AZymcTCQ zM`BI#hUwrbnHQeh`1b|6Bn6qx$!n`i*#&LoywvF;Ss8sh93v4uCB4KMiuzNq^c?<2 zm<6f_=I-pM>;2WWkKl^b+m`~#m zzYc%(cwOZZC{M+?BRLmi4ex}#@ryaQ0rB4smOfY&FZgTtOxTG`@cgl4D#@fqZ%Htn zt+0(54S~Mwij)o=BV88Jieg7VVbpte_Q10io&T6~tW2y|@mc)8z;sJKT z&{=@P0Cz7r>7fmX$W_UGY9*H=b8M1=~HVzqzAW#1T?kH-8%QG%XI?IOXds%^R;XJ zV7LvZFoHvA(v_W_FUo-EB5+hX?1Uj4oG;!p+LJ*%2XJVVqcLWbeup}U)qfUN)Ftd; zi3F#JlX)fL_>gO}_VWTAQ;q@%Lu*G5AExC)(WQzJ0(Bx!Btv0s1KHWK+6O+2U?+$L zus_;i=}w{xSPtPKZH?%^9>itHb)99%PUD)B#!oFur^Dig*t9p}Xs!7y_$_d)xQb8A z8<2+z{6zFcpgUr=Gia*1hbiXfjUindM8?liQf`8pzPe;ui^Hj-oq@RhQ_l2tVn~o) z8ou$m@&Js@Vbx^A7UZmT39a*I!LCB4jY%|)+--%%h#JRkg%XbFZ!}lO0^{*>lEDgs z*k*Vh676Tqapw4*EET#apbE!0!e-{EkJrv7qSO-=Pt}zWG}#5K(}Z!2%=IlFRG0yC zR>gkJb5hxWULv54La@;&O$wB6FG@tm?QK8Ut>Q9RbRjN-b=d3sgE`Efy4hF@$ zQSqLpcy6v2*8x^T0+0OtKlg-^bN!2P`Yjm2jG%c((O|@Vtm_KnUXZyHqXfqVpVfaI z=nA)|BN+chU7WLo#jD}4j-d?s22bM``~${7OKZV@Wc*={$V;vvpVGR%08kjY<(n|M>IweG(P<4eu^5Q;AS%(A+(_v6#8l`XKLyW*h zy6L{$55MG1wQ>DKaTWW*%f1^a+T;3Qs%#@M(I^1b4cXOotD^18OKN<`qDl5-eygfR zA;kgOvp^A1ub>vVcu|R8LLyPI)Uk-z|3GRb9XF)rEm4R*CdoJ_7pbxYKaA?VO2E1Ts?G3Y`U~O&Tt>QIk)L0XPS9YO#az{HTLGvU|$S%Q^ zsk(NCcPe|_fXr43@_M zq^|=FhZ^Z*zYtC%(BeUUq5%&`*@U{GQX_f?o)2#CIqtBw=>Pn`MzZEfc0fy*NWB8k}c4hzz5`jbs$eBO^-FjU$hmUmuZCigpv3&H192C*=<0>?i&25{PuT zP?8eh;?R|}dG9GNw%=O_n!X|i>hc3be?J; z8#J~YW?4*ku7;5E5XPK0G3=c3SCqiyC*9x7(}$yUiruCk?ZY%IoeHNLLM)!o&>yW9 zWG#%)DN-rP@IbLKS#zv$wwmBzW6HWRXREpP1baLta}^@nI-IVOzc3XZI3^u>S4F9p z6wP1 zNj+h8y8-40!QLwFpQRyTw2kQL+Njmd5vv8A)DR*Q`qz@6r)Q$QYzs;OXj>E=#~}+c z|3u|I>MouHnN(_x3hj~9aj4TY-c^FN#u!I7ZmC)$ zwJEIEc$h{&V=RD9ZbkjuYIrbiUsAxW8*opmO=4Ph@Y;-G!E%HMMlI8j5%b~`t4Li? z8{DcrGE51eh|Y@8fYG;cG2W1v&7B09HNWr#G*b!I@wXG@U#bYo6A}(Dr35F5fjFeO ziQ82YHd{a8K;_Y=Z3u7jtZ|>4c$h0-(1JCpV~f~PNn{jEHZgS3RaF2k$K)xlGv_>6Gbq=*B2{*&~21W^7AwsU5qWrcjd%*_-KHn^bpYf2yAt^7H= zvS7Jm#u+@prgoA!)@Z56<{*!I+jeS8s+&ck*$&Fl%-37v8PZtW9VEZrI_7i#K9)UD zG4^>be=C<-B;f&ov>O(kAi$d4kWWMb1Q58ebFHB4_l7d*?IT0C69x6KYw|I3-9YyG zp4h!U&6D#H?Bq?{A}gc0nbeW&4wc1IbK_0!mN)A|MxQwahQ!JfmD#k2kX)2v^^zn1 z$~pMTw`hP!mP=lu?6r2;qB^Zha9sy?mFoxfpR@WP9_3E2p}Q_Mste<_p(_YT{{dA| z`0kd*?G>E7m149n0-MTVz+wMVs6Wv?C&U-xyyw6n%?tMaV3|&x6N>PLOr1&_AlD1< z|E5M7+B<;xz}hC*3(Y$2s@LfS=RN_i*Ybss8;{#3{b1~-;tPR4F}u(B2I)=H6U_P! zl=wiEO8IA`@qRljY$&@kKm)8f=@lRbUy^!g*CTE78bDHy9FbU&8Qi$X%8^&o%BaabO($j_W zn;W9knG2W7PniD<-m+fa}IC0Ja(-6uJ z3lXl1iFK9qM%=~6C8`{5bxdw(rRF_3(`if7JNAL?!R7m$UfTl*RlWSGJxRn@0fSC< zAAIc_8T#pa)9Z|QN;2oU%iNR>*x3hDV;6j-^p-52_UWvYiQkoJUaISZn}y-u9#GlB zyD^#Tq`}GlbGS@{_@se}D=Bvss_L;4uZk2@6uiVb(MiDL!>MfBo!C z_|C_xYOcj-_^;n1gwQH`z8;L48~>zl)TI1G=QXRYhUP`9I!?GRX>krwxl*6KH)wYB zPbaI=v9?pzXd7@j;YY7+rA7n>`+hoW8MxWKk=a@oP!Ff?0g|$uF*X5nTRkaSo->a2 zXg+TP{Ga>&9!QRkmLf=lvCC6dCwQTf7eM5T!w$b09tpv@XNlj^w%q4=XTohQk0|7P zDrbB(M%`KlZwyE#A;f_09Y~K(WUT9qc`508Q;#N3#K-69$5_hinuM~pC?20~AMN9d zBO*CHyFH4>=NKY6c)LCK;|pw&-0J^AHk>FfEuMTXYh`lD{C5|xhG!>3Dl}KhF51M> zTViVJxLsNUYm%jHa8*2nwo@?9J|qAU0zizaST87720~{+ABq*x7BN%e;|_-2l=2ok zvw3zagYXGE|Ut^iL%a)`~fYQcRH3vU|HSE^MD-(t#x_XswcneGygY){69c?P-6IC0=u- zqPrrk|CtKrw+wBtUpeW0uO?VtCGr7t3sSEV`A}RX5*!6S^DMeI@n!)urSs z*{YY^PJgee7H4^ud+O$BSOvF7Z)cXA{M-G}a*uavXWpC&{C$WeIiJGKA+`!~pM1-` zUWKY}jA!~@x$Be7CE~CD=1|s(Zm$?%G*2P!34J-~oBq<`w{~-kPj&9`Zutph8CtNM z4>HbE;aS-a@y{|fkysB^tWsSR(o3m&;Vv5QOD#m@+lc5(0f*X;ly>DWZLNG>c-M-b zaMP#swTfQ&*|ORp?n}$NpbxdL;+~Y&O&VZ%Zn26t;SUU*6AYmkb|?*7qH#t7O;wCC zCez}vh-hi|;yIxmqvym{%&ueEf*c$6pJSs@f{$uO^I&QUn`uV zbcOQ8=!wcWh3Zf&<`s1#xCot9AfXnc?f|&&^%Hp_EXLKO9I&bp&jw(XHlXE*nDn#} z$$d=$zG*2laQ^V6;fwg$Fk!>H!Ww(9OW++5IdM0mIl^w{1{=MF==)hgcc0-Mh&$`) zD_S0TPTSU!F-T`ibC3u@PA_qP zNe>?o8ZcqaL)N$TvKGM(S;C>4H@suFN$G}pplegNhDFxJkhIC|5Ydft!EKYZMo2&B zpO`t7v?D#(aN@_prx@r%P9}{VIAv}j+Uiop^=Q}8FV(G4 zqiupJ61q4J)qVbbQH_p6xXF%&dc#xM@U?zprdaJtih6o_Qk@nTN~8o(cELuTa|w$< zOxN6DymD_htw0$6OjTD&JIwg{xF@WhiHUy(_->aI^i1soEhfcn!cU^CEkfqC%Wiq7 z-GtSspNNU$F%^^R(4X(TJVaO_O0L5%U;&7(joaIK_JllLUHg9GV>T#*%Fb_{7@wbo zX(F?sBhGNxK|Jh7tI2q~L(X1%?vtlBe|k65;Y%9`L=A3H7tFmb zX3WAPFASkE2h2_FP}#YD>W}K#ast1^n(q-iES6dnnNo?agBHJi;*<7%%iF@dmakZ! zG~IJ~$9^!d&)Vv%6^(yDN!&=_+)y@sy`K}m(RfSc4LoVEywYPcRYRO1m({@*%l%P` zkUFt>&rPZW7DDl3NADa&X{A}Q3f9+wN=8N1EwjO>W0nkR971!=G2y&fsJhuNnD=fO zw6~*C#FE~uut0IYYT8A#pnV;vM>$Z25FWS%`gmwWYU^+QU0rT^9D)VjUtc%64lAjn zI|ssH!O4cX;{1H& zGhL-Nveszq$;6$BHCy|dxsH{A&keQw$oYWJpz=^B3&~7XL!od}0^Bz&&5;2zHFvcbO1#JkAdz@-5E4Gv8ke$o?{U z5S+vP!xCv;$j6>9DVSaCm^bPU8<-434t#)W_z(W0(w9MAtf57<) zs%zvLDO!BW^g1S=${U+sojFftb&Lq>64?HeI+m){HgmYId(^Lt$v49Jk$?kNds2KH z!PD~cm7W`5L#f(;geVY91mQjShgeV|cSC$MJjQ%Au>(%m5bgjC{K#=zcwI!_qMr^X z;T^X2n|Q9q8nbf3QSCu<4MRvhnx$G&7bCQmChUUtRQeo5p9o_7EB)-^1M?JsL)3k8 zWPi_dePEVZ_f{r~}y{ZDqIiY88W)~+U^7S<;JSL%k+mhBQh0w603dCX?>86-q;Q9d$> zUx(rih2-xcrM9p<;(artRO3hk@m9p&yaBC$MECL(NZmva3gH^$;iVEG_@>^bXVcjm z4SqkruYdZ{ZqFI)MaQ6Ksg%a!HC74=%J(^8t+-~508!8kDU=ozR^<%EttHe$T`&$! z%|r3+cRh$O9huG}N48yr-)G$i@+5js*0vfT-Q?O+ zuEj6Xe{+|R;Y)}sVKn~X8?Uoib#;%?UT7?Q0C8^HXuiy+**0ln$>f{b5uZLUyekKR z9|k;!;ClXgl{inE>;D5!x}yhCDL4` z2CJbQEaS0eoX#qdKsEzeIN&YgCiF#cgtCy-SRy$l|#i_^Ilhpo)Uk6T2jJ!|VA=8Ml1dBQNIdQRr5CX(U{@HEu73^H~K zrg@C^Zu|zlR&wSMVnYQ@W0YFOAR&n3e8ikKG7$e2U%>dV{2))P*4q`cj-#qbdp9F_ zP1qL7`oP?!}Q@l`(KT*S_OMRRhjAO*oh<$@GNhaHy{<*a#wZ=}n5{~eH?Sf$Wc zcp#vCav&hd|9^lenK=Jfrl^y;jrIQyn;K0YedU#ue>uiXc1#}e4BnW3VFMAw3BvO+ zD6j;P3MIso;(-+J89gNMX3?3G;=}P*ENfH+np-7HRB0A9w+hYmhvk|zZEjXuZfaX< ze(LdSw{C5_ZdFSf&${1Cne<2qx4s{4JI->Q{_BeKx;tKp%ku{7|9Gy%-g?Lk#P58N zdspCfyzj*R7tMbBWc2YZJRrC8j{aR0$X@c3fo8cX(NTHpnEY81P9#QiV9; zxC;Nrv8gAOeFD`D2YL*;u>mmZ!ru>fl+5!&2~c&3q!VV5@zTx<7%Edz^Gtp-C>EW3 zOpqMX`3;a12o|LRr)~3mjlc}rbSKozBT?p=6uFB0Gf2-~K@;2RBF6z5glWM5s=u1W z^B%UE(r3`75!h)0GozeU1N_)$q_bk>+pUqHtXy>)&F`+U1Z;pfQm-+-qDDIMneS;9zOFavbo=pb1kPZV?E_Ut&D7Y4$NfhbnJOd+z z+0@bgh&mGEv^i_DSxUIq%N{PUqWpH3FLo;<~a-VbS-m znmj_v)5^`n7`=()x;DWcML`F^t2{V)E)J*Fo_)7BtTkH{Kbh`s;xWNlWXXCCo3@kv z@%;}%AjCbqscqiYkHH!sy{wfUb=J#*rDBxJ`SL}AGTJ~WnpN^mf_cVAYtLRU@tDX^ zEeK>Gfd#sGXe(Aj0)E;o2dgx^%!whP3cPggAKeWYyA!b+$NRs8N7v@2eBVtT(JX;b>%WSgv^G} zH7wF-_p8hqrcb;U)n&Nc)VBtz&Y6T9SMQ~68j;$m6W4b)iZ-YRlb3~A5hBT}Oe{3v z&><=5BIJb$Ip7e7Po9>4c!iK3?u2?L7dzQVM z=Per#Vpa^*&@7gT1qGZ?*$&HChx!RK%9rbuz-iVUT51=~gQc)7o>18o%2hOHv?9#T z<_2P4Vz>B@l4dGJNU9;wi^;HcNNPPQ+;@d zv_s)&a_%55a1c;|L7tUGwp4D42R0!8$>vpoT5wGnY|fEqjePFjd@N8h_L&_fVju$f zKrYcu`7{rc`~iW5a7MjRKDSJ%EwJ*i(sY(tXLdPt)@gjgN~tZ9t8xbHIq)P1K z7~)i{gO9kWa0|s$Jf)ifG@HD1-OOUrFHnGjMFL!f3yKkCPsLUD=v>7Mi-SBsrgY6b zGZjE;uHu;o_bf;kEDkLeODEGK_Eg!_8LolsP`dmv9l0YrjD8X#9FSUSe>3 zWIUOzI!Q#swUY!>;CMYYVr_+Uvk@PMAav51ORO94$xLh%)JXB7+nU{h9hv-8Tal}j+1@t}O~Wc{LO~N?S5(pyV%a8(oP?QY^E*+J zq2BReQc9>n@g+UKW`^$!H8{~DQc_`7OJlgC2b&%0V{^>Scy+xjNC@ahH5OpYVUib8 z`$F;j@@B{Bp~i{^w_H83OP;}tfimQCeea}UKTs*T5SwSTz7|I7r8_#^VQ4&G>ad9H zYK0Rn?94;f6F)nqbqi-cytNelnh&p0ArsQFaQ*yO=8D`&i%cTNN|+dtHSNqw!?THn zrEViEsF{3r6l|}s8jmz6Ztg#~n*9KhSx1zVa;D2gCd%t%e~9Fq=`{jKDzdV4>s)Kz zOiL))cm}i#AiX6`U?S0)QBuu7bQL~(kGsXn`dHD24Q4XY z@}rm}HOxl5m>&$t^w%!-IEcmFK5{l8nS4w}0e*0#6>R^@a`AKR80)`LoSHRUqBbc* zjBopXN!Gxaxij1Q??cqsMlEfwI@(s(qp+#j`6%6S=P$7$y+BDusVz&M7=VW3j|K%9 zs~+HTa9~${*wb5Tq?%5q?J3>)as3Xi_qZ&BG6BZ83GIe(*|Y}JC|#9pqEqQ!@v*x% z|D%~RaB72I`$N;rtm=nkl~;Rz9mhyjzLvrC)CDtv%E=3&DRhPLxBk=+HLJ$0-DSwa zd?8Ll;Hnh`bHXtKou@&&=;xTd`ouc6!Gn|9RAZ_)e&d7&*X#_oi{0&5yD1isLs|CF z6WYd_`E8ix4poggu&GnVA@k08>n#x%Vr%t>w!lUsxRfb+Lf*sL-*YyAPFG%;d0Nk+ z5p^j>RZ!dqNGJXyADxY>%f+g-puI(wQ9E`q(h--`do)GKA@mPIR$Cn&Rd?U3vAi)BdG zw(dVOv(IeN&SPsgEc5+C^QOuG>%i^%i#YEsH>+^W3p`dtb~p2#g5MG{86fq*8LAwG z)wZu{3z;`&BR!Dl$li1eBHE+H7TzuT%aQe7q|7xLMHDpNhfWFl$&w z8NMYgU=~SW)|h`GeNN#z%0LW`3v)7Jk0vx`&&HgrOf?b-Gn*_R0yf7;s5@DWVLEo; zWRz~yIL456j|62?u8t{u@jZ5MKb@slJ#5E2Y7Z}R)_ z8$%VsC4)bYfF~>^#Wv~t(9jJg?Y?+h8FGjU94^-zAW_L7QF}oGZ^Y}jwE@hvZm?Pe zk+lwBFGA6(hrmi5h+@N7_Xlbv8m{fl(P1CFU61m)9{t*I!8bU=HJ)y|Zmg?c>K%~% zWb3-{;u-pC4}oY)z;07wY%?=JpBb_3^xryJ7qYTPZ`rrqjP@E2>v3kjE#hv7dp+>= z#DkxotIzWd0KbUi(C2zkxgIT{7`v$!!Mjq7)q&y6XvOGq0Iv(!S$A~^c-@zEec|y0 zcRPT-zP0tlc5{+HEezisMt>lMi-UCzqqXB((RjS4nHd9E>x8g+`@fw{;q1Om{Ocn4 zXVgr&UbasSb;}1F7Fg#SYzfT~Faw3h5g-Hgn#Ug$2+lX`Ve1`(iCaAith!H#(_D0m zrx2F1t@F$DI0=`M0$<1#x^kTbvN|kp739KL-7xTpL1z+QFeS}ruBq=eFb&#@%%aQ{ zi5p~I?VKEO$IAFJki=&e+EM{?;t*;Yb&%wBz~lai3#?_mtD5xYa%#gpVthrj>zY+C zlqrp(gFgf&wGdO${dLrxmL)CLKp85hk$fexdWz9{%&-G@p-o6R>gZk;+)8PX%3lgm zqew}u8f$0;qnm-{ky0B(zK0^aV~8LtGProEjFes5XqYy!Vd8Ykd^V7jmWC?`SCh}` zjLB6IXPcijKas_bLJjY9hxi(Qrw=l=;EXe>%@Z(!vowQaiOUg6eUBnGQ-y=br!V(S zShlgY@wKb}?}PDnjQ)YeHw66wyE}C6Q0yIdcM$&`c(;V7TTJPmJTriA3F z@a9O7nyGo zFy2v8s8~w($b+PG*tEbh&V3Y~q444GL5VOFo;SjCq2q7d5Fwb44U9#1*~ZyeV=n&@ zlEW8|(6}Seu3g(hwzMq=6Z!!iG$Hl_`Huo&GF6agfyAyc- z|8FGTQg}9VIWQ0q_8%Z1_Wwy;F!|5JnO@k$)WF5sS>(S8C3_DcJ6mTH_y0Q*Q&C3> zTL1-+WbK;OzG`0eQso=0$O4ZWDUMI%5fK?;j;|QZE4%8z+&CM$qfzm%5>!O~9R6M` z!i|khleU?6d&6mN+iSLGN_$WH7oaAy!Oz=CFfVhYH118i_BuFcrDjxd6XU7g^LE=2lO{TzQ&78e@`(S(ThHqUK zpI3C^XV+A$7|{6m0AdmvH@6#E@aawhKLztbF4-Zu$#>F+x(iF%P58)XMVq8bvZ%ah zSNo#{I`!S+WTEzi)!m_r|7Q78^kzDnPJsYc=5#s7daJJ;};GdOrhtHCBn+Z-VqbPlH4x8$@3ipc^ zW&45l-)JYisMuDk%CU5te3) zNHBkMP1lZ9O^fP{rCQDU%|E*;)up|TyO}8x7{=$Tw+!~TUANl~v!5I%eBZO3uwDV- zrjI+k&dA?_1wOzty(e=P(>ZOPxgo{y;ZfB zIhUEc#F4d!yYs8(#y$@G*&_!1*@Jq)+Xav8S(9<@-3bUDeH_7 zm)y#`wZU;13y;jJY}(k@u|q5aKn?HANxm)beE;)#Z^ zkN-5OhbQao+`Awgpr%T<_->eUHqotk_JOC{4-L>BNi**jKO1T66=qYp(k^nU2}^rq zGHBbLa_Jr%qV_0=zI3sj?@%bVUGzw?SEo%f%@+7K-ys6CSowsN;8w%4df{C$dj;qY z*g8&*;j%;Wp+~M@yXqD>^S58GbdqOl^IAWK)3{jn$fCeb9COWaJI7h=klGb9rmS>o zn@zjIS>mLtx;j>%2_rFHK03(hmMZN6bcfa5-=}>0V&0^Tfjj@^cXvsO^BteSKdI;N z6+Wy;-`Y1fEk!eaToyIVM!L5f&Avu@wy@<*Xz8t~cXjl(I%r%ulC1|jRu(0=6Cp@c z!v=dzO9x}?W^dKMFV0kPp&4pL)BtdC4+964Txl*KL$+2TIB6sJ?Zt%hwIJhAOc#X` zV#~{+R3a-++*=kAAViXb%W&vPGISnf8^o|SM%}bpYamC07II9j;bWr*j-{C+Wm^(5 znx`4CHC*Laji>-YKGGcy%y?tlob1fjf~Yg8Q5WAz8yk02SjMK{;OZAUvOp&qorlHt zB0dy!cF>`rL%Fxc;?vloUHZx3sxxcvSTS{=$Clp;`+5B|e$q#A%$TjJEeWm*7J?MJ zAYNfJEvC|`Gq0x12-3m_{~8fzs^P2~+-K-_fkt&GiTb5qIi*L6OoR5LG9GdnTK_bS zCxyFme>)y6tm_Ysu=d7U(992_wUv}rQ6p?QnJN;qjM}E8+rqkJumT$R1tF_lz&Eu7 z)%t-$J+JQZ6p~0Oi|37}8HOT761^9X-x&~d^sQB2{rUI`9>_BqQ$|xGPID(oW4+n8 zRQiXh|4I@Hi2PZGbbV3sm#YmhK(mk3bV(iRalV;iO!x}=O7OOAwmV{18I zw{Z%#Fm~P+=Fp!I^L!Fq{x7N4kz4_kvq+m5u0^$mB8r_DOY2a^Nx6m`gLx*^`VR1Q zgnm7#OnmgHtHmSz_MgE>Fo=V9X;9VBbw*sl;w_*e%|hCceiwe3())j!!>-JD(IK4) z)R*^IW|mRVP1C>hY{aI;`rmRknQ%+O<4wbPa9|v^ug$_A=P8@6g{O1Vsbj?{vvPLGX_|U_QCMKwBI97iwW&S%wJti4icpVO|Q%B{@V`{}Z12Flg%3es_$OU3ykK7T`1tJSgq|4YnaR6g>JKNtD6S@d84n=$ z)A0RLz}}vO{H22MPwRl4wNzJYG*z^W?$->&5Pbh=eC$%djU%8eX|5`(t+h5|d_(L7 zkUX>jhrs$K<1f8C1m*3Miw)RV5TM*f5VEwCL|t93v8-WzC%->iIGDv+%KyA#o7v`7 zJ+Q<6qVbvDw|#J9`K|5WJ-o601`N#I?-0DA*Zh(HLRCaBN^g;DxZ3&vi_b#*ry7il;XGWZ z^E=G8RHwhOw`=r?tRSDoEwqr^-Z!Mk#yhl+9|fJ4R&Jk?M(^*W{ag9y7~^Mn5B;qa zbc>o~O5d=6tNUFnJX-Zl1haFBZe_>xPRgh_)kv}2=~%~Ss=JE};^xPKBwBWHCm2*C z*w4s0EcvdI{8@ zy^1x=6nUGBScfc)f~eONf-SHzd_vuVKZpwBXT$b}Nj5VMq%czFG==0O-{;y^#m zInq?vpWMy-D_qpezJSi4a4&(k&V5*roNkIzxHn9bng-u+nDT=~O_ zU9)V{1_c$83YKcQlNN2q#O3HHjQC3tRAO<%IWvM}Jul01sR9oC@Zn?R;)ld8a+y zm27?xn+T5XG(h%bv5=+hmSuy=;c#en)!Ys6nP2a8MkQ+&wWRF;4Nj|IBuQ;08t9ce z05J_?%XK6(PVI0SUsZUbe};7`8VgDy{OJM0IeHaTP`)zl;s{9}RivZr*Wr z@zH78fTj13f`#m$Skeg?-lyg6GZ)e9U*JmoQG`P(aCMu%PKA9a7%_vl)JE^NQFBME zAVh%+v$kU&nkZH7<}^D+Xn_`-=2-%$-d0dYnB*3y%Oi`YKZT(fYXC#&E5$@`H*G8{ z;KrzL{zU|OTKszu-aIQ?3C?;7E@0g( zNPuq+aHe?IZB!38oY1coL?c|BMWhpWp4tKdIM_3|9f^q)o?vmy01DiVSQNHaa@L(P z>stB89fG#6gm6vm<>Wt$1bSqqhN~h&Emnv+kRUVv`QWA{rB%iO#fA_*uM>8xBAllJ zVK?$GQ3TZz5wU+9L}Z91G=j% zlRNmZm_|DQ*e)e&IcB#Hr#S>N#U)$;x4bbo%09wFsT>zdQGhSA>zk@`pNoFd_=aqq zS=+|s&-T~JIZ(ft1Rg?x?iM=^;&e zOwA)W;y8h!x>BfHJ#^EFEYuZKsN+I&6aDaJnhpmg6`ODgbd>tCkOq5E(B+Gn$v^1c z%3mEt*#(8W1L=%{3nX9KagLkuLN*V!47|T3$3J@3#{3%P+-6qVM)5xsz!;R~GzfGW z{CimtEgAsut_!y=*HY`~Clp^&L~F{!0{epyuE*>dG3|I#O07zEH&m5Jqt(Fo`i5hd=lQWpbELb zi6pS>ybz2eL_cf}@MPGGxZVyiUx!q>3+1f!huo`+W(8kBFM>Xw3NNLRugmwk;7t)@ z?9A&el=c{AJVD$_)@ym1D&(>j+Y_Di3`@0q_7@ccGbim}^^`9vS`8E(Q&;_D;i_GL z{2t>WhcSz|f6Ae)#Sw$L@D61X2S`x^&O7jcdn!VB#E$YGkA$2?=y*5cHH`7r z5^2d;g?E98hk*EA^pWxchX+1t+L!6;Lbc0@Aw>!;#uuHq231R{>69Gg^$~7rqz_Bk zVu)F7 zluc943ey^#(a2&=X3V>JqT=;mH;Yiwy*8v9T+NC^TfbM0%|44xQ9k!D%Yf`}vXAVA zbl_+BAkNOc&6>$4=85m(pL7Yr95WNL!ZLx!io8nDjM3x|OJy3u(P$>U8Yp#CG?R)K zUR05P0rBtTmjALKBH9dEfvHSNqd0{!Htldv^XGZC#PKTqHT=xelB_4?H33yd2V$|+ zdtp7t;itvbQs`fV*Nwg(c}kzg!@mPFgnc1 zr0#AerdlxY21C)a8(rIWlvqoXTQX6io4ODN>W-Q>*P>}eSgjCSKnD~V z8dyVo05L$$zuPrIjqm?r&4sXpkS~DbN>8~{vDWjI46<@rvX&~h(;T){04L>*@or~^uN~YZ{PSWgg=_BR;T+{YSop7$% z+)Yu>O>5=e+0H@b<-edwL)KWg?rTpwRM@vdg7(bWs(rU|Xa#GwZK(iTJXe`7u^G!3 z@D_W>Fj-@p>Z!ygLYJ@&Su^mAxu9c`hHTXP((7n7_AY+8Pka_NFSM8pF>Z3KDV_Ti zq8EetLdS?DUV|n+1vFFg}la8Fr#SlmYrtQE@8V0F(vyfxyjCtXiVETRGfLRMStlW`U^a<$LPZ* zA9h&w`2JumzNY4~`OAXs%?EpIge7GX(U93+7fl6pPG_>|9J)82Z^-!^QD0{F`2C5D zUL?&O%DWw1C+*%uZ-!K7tjd#=?hMX{SM1e+nSX%xi>ppi@q=mNod1ha#{uI0>f=|Int)A7_GZTmVKfmq=ef1x(|%Oy4j(J4y6> zU45zGDE0@d7+3t&ErlpV$>l*3e0QGAc&xev4v?BhBHT6O^6-S;RWzgoM{YEdB+Cb! z;m0O$bT>e;(ZRYj8_5z?HLj9VpSHibS$LZ$sHpb=%bwbkG>E)d#zqZWsm2J?XQ#bh(()aPGkANKOI=Oyxf30Clx@8Vlol zQPCcCYhYR##Tuu~fCM&J(QSo+J2sdyCc*_5Xi4fD*_juN%Ql3reNb(i@G5uyWzL){ zzsom>3$MVo1uVp~t;x~q^Iy0+_plCOejo{ud^@bnS=yr>U7*!$mP^r~&7UR}yz zt0!`=ZM%kKY(W{h1)NrFdSfzz`VAW*Y@+^JlxA;&>0ygFY+0IF>!d8fj_Pvj3|Hm& zce;$%g?6WsDy>eTRH?~D346{n;DvWckRwbxi?MTGpTLRsJhR6k7pTsYk}pi$=U=va z_64}z2xnps7fINuq6LGE3x3i>MHwOyVRPWmj_?xwiK-Y@N23$3qm-E}H%Cw_bR zflCS(ZUndv_3GWX5pK09PjSs~`eZx5adeF`TnzJ45+yM5j3pWNwB_;Tb1k6>b9GlP z!QTcIoe2~lD|dlUb1B-re}Ss(5-2h9OQU_^+Mb*uozfQzTzi{5{7?eEe*U{5^c7c2 zfF2GA$e$btNbr9qQd`=&m^#@R+RzKx+q*csI2k$!+dG+xdbpU{Ia}J>$r{=j{+D1q zq6Oulql)%do@sotySr3&qgjU1wo`#jyUYcc>pYjtR;n|;xq>#occz;}nd~u?-F^WT zBbb;X5+=Vf9DR5tq=Z5iyU@S=FtDrrww;V8q7vp(g`7-->heq@qIIV!=>m?}@S zGF9Aj)R=$ZB30>Od!QiNu}3kg@S6xFUxfHSi&wBXm`3@CeR7e@#lmMSw7ij1R3E(& z9$fkXjN#8HDzn3JWFN`yJ{o*|q#=FPd(>XFz`Ck8@LtVG`~A(rXFRZ7T2Z)Mx`EeU z>#wR`K>RBAfG-W7zY*ytWk#8K6>prs3-;2e)b>3ne}|ZhT&^D6J0)fQcj1+!l2TKp|B z#pbmUqd{XLmig?D39!N8leYrduJ3}Q=9J$oPxPQ;MO-m%@GV7yN4|J4BBX?eiA=9! z6rJuaQQT%C<_W{UA*$v8G?7B$Ati>1qSnEQ3cYv@F77n!@uR)Tp}BcJZ`10>m<_K8 zBjr|i2JKmy5Dz}7;jd%ea$0D3KLr`$S6HxudbJC;2^HpHx~y*(U>a^au!8O@Xf02d zT8`OB$FXIm&M%qcAQf!F^A>XdzJMojCCug~Q-#WH^%#bK#>6Yo2zOmajYw~`YtmRL zYkZF1sd{Yy35)i>woafwsesJ#VvvR)gZButwtvD3Xh%HRB>IpYx65)g-3niaQ|gTi z8|-xhRBd7(%r19;{u*)8NUCM8J%>D2oVAu6>v+L%$6$zYhz+U=&|8lij4Yh<%^VCpmZN^IKXNeRnaw>|fxaX*#A8iCPMc}Nl=>at-; z%M2#j(Qd!4PRVBjvp1sospsm4KUD zE7(yBnw%CH5W1SA7O%d*!!tdmW4}|u>(Bn{SdctI6Bjv)Wc$_UIV9qAH+jl`xOPjG zt+Jk|+73>xkfa*dx2DStj!vG@g42n1He;y1Io*!NkZH=N%W~mqmC+x@K>Z2ZtbEHD z2#5WmSP+W0R$++YX5IeFHaOF#vSg-I6M{ZQN2Ry`&l{C$g=0O{Vl4_jWDC1Or82&B zo`p);qEn2yTxW=Jt7f0!1Cn{sZPP^a1IdtQFf(DWQMofL4wMKtjn%mJG`vN{A*Wzo zCUYbuR4j!>yNJ^Ty}%H;pm5)8t1uxfWZ!Eme_n@6yTB7WNBB6Hv%`D##DfAC)l^%P zPOJ9OBOA89LUq?%uuwA@_Dk2YQ>^C>nINv#Tub$Y}*psV7Mfi7U&j><{Y|} z@)S4383Omw<6!Pi(Bi4&FwLTzW@(O9JGxr(%vKa^8JZoas@bWjlovBzvtQg#4qFb5 zL1JkNS##aGMZC@GMetVK#x&8H((QDTpP#is#7QKen((I8Z8Y4pkNCVNy#CD2nH?i; z*@V_s5R`)t_d6T+FSlr`T8o{qU5tkh4jJrz@C5fC4)>ULC6LEPnI`N7{gsR|DW{DM zo>q2$JpkdDVayhZZTz|@JFiYQT%Fi(P(?B3_;Lc#MJU_j*{R6%^m$a>o)dp64IhhL zHzr-C%GOG84|$ikL#4Up$rOvQ;G2G;SfS#mph|FE-BQ^kA<)fJ?RZ<0*m2H7AlkiR z{>)U9_=;&jT_{vnkXtp4Lq8LKT9mkRq{J&_$dfznW5hXR!n;mfvXFyEJ(okW3iY_Z z6;ybwDHzeCJcHvHRGE$z9rUNv*kAl1HKMY_7bNrGf}M1%L*A4Dx7~Rl_RD9?ds4&V zNIRY9G!}7c$?R0{5JFNL{($bm$a$yBiwGJW@KBFcOcZG3P99k^X8swh=la=&6kC>r zRMMa>o61TE=Jj=`ojpY^N>`jbIu%_z*=bFM9Y-2^xtEA!nwM8-g)g!}D`Rz&d#~Bb z`j)iN|FZ!Tul3;7&ON#j0;kRK=O7_1(Xq&PU>JU>JJ)~$oxvNfYMp5vdsVI<8!-HL zc=l~_)ZJpYhC#FJ{T>&2 z%z>YA0h}ebEAVktf~t^^P>LXs{`T37PB~2ZapJ4S^hj22leq`t!G@Q#Fwua0zv9HC zWS4h4)lU;Nfb4T$;^JL-c8$V$v}1_)mv?aEbTAx%yPyi$!dw5&=E_5 zVivO65yF7Y&+J~jl362JEaxJ#5fPmjwLh^+co9t-)v%>n@4Eo?u8&ZPJzw@i7iO@p z2N-mHp7-s6J5ryuHMjt4OPPX#vO9DL>vP#&<$XK8xFUa~yx{%|p%i4<-tX{n7zh8n z$AY^iG`if4>7=y#C1%eDFdkPp`QMa&y2s&TrtP@#v;}12sS3>kt-+Ncjn7iuk;gq; z1?4mLgMz=_suW%w@zI>UtnovuS_vw5Rk_2J1}!cA7H%x2pU|7B@`}1X=NbgVAf7a;ES&v00NmZJzv*K0g&j3|*Ryl5>&#?miO>KQ8Y+5N;17Rej(Z;!zuR zDlLFOTA4JNpz44gz>;;;8#jjU8F^yFcWv;&af~pg|A8->)g-t!`&ZQ2Td5L(R@KyS%Se*i@7%Sr8B zQH=N_XiOJ-H>g_ra6r`^+M%(H>H`dgIGzerF3|cb{-0!N;XD6xR}Ia@Y-D zXYQO1)#iB8nR)6|tVwA(pWIBXnF%V!XNVv4TW;j*H;ut*<$?N$P+1Q}QBS)5w?<=s#lcY7LQ-3eL;4p~gu+yQ>WqhrV4f0!XG_Dvu4;nb z-!%O93;tuO>Kx&ZFu}0ne%RD<#-Cyw690#4H z9IdD;t1=XGO3|LEPQl(a^v-~pSHPo2ZOYDgUzVfvpcH$9IHWuWSFmdIq*Xv_nMArJ zA_i(c0S4Je6!P~!F%t0?8@wfcOy@bee76p^AmF(A*h5JKx8`u|E*bU3xM%m;F%LDN z&C#!>teqeWy#BpGMc<_ufPEE?bJT?q16BN;4LU&8uNQGvIk6 zC-&MC{q>ptiP?3{JLOA1_Tw1wp&Ff>HQ$rs8I@to_t+P9-xtjM$Cjo@#7rol1#*Qc z)q{NTxxx3=pkk0qTzQ2vvvEcdD;ca2Ej2@?S){(hWD-i$uxwrCc*>y#_Ns{K3c6&3 z1(hdG4$S>pN#nD)fsHKs`8V4PM)^zA+t%pLH!x4qTw8{r-QzfNOw za_G}cAV5G(zkq-Q{+H9(e+^*&W3TAH`-eP?O&$L2;@^j{66H-h6h=f|yINgzknnN{XX9hko-_@P94{N2imwxwOxmP#fihxAZ?B2Tv7hW)t=lwQuZ>)(GefaIQ4!dVfZ3gv()D9Wqw@oxu$Pjzd=T78IM)urH7Sf;Y3e@>bF>-7dqd?v@*0H7h zjN9z67-?j}ZOIcBa>RMjT1}4%{h{|`h}xr6Rh%`P8{qQ_MrDU%Qn$Jfs3JVI-Ae4F z@hGq!`=18cR>}5h#{pSi0zau&4wk&JqDK4wsdBndlMh{m7dP=3`O>v{(Z66}ALYY5->}>o%n)w8lNjTzRB1v<=n$#fa5vqblU_Lq)HkdMk$J9s#!qIrtz(ni_mj)2? zS$d~d`1n8CWfO8cs6qJOFc|#$Ls1da`GEJYJYHrdzU=(NqY3!`7j?k&KY66LwKp-f zq5l_=;6H)Xlt)oS{d?n*v4BpgjfC-QbwNvPI0Xb6GPF3d0bFEgXijfZAfsZD5;O0M zz1ONR-r}Gtf?tZqd_#ybDB}J&+dK8P%e>=t_12yrDB6%OTF$~Yd>=eY5uIH%Is~b| zh5@ThxP54J8}X*Wmp|BXB?FOcjlaT3Y6KJw0c@$zR&^2vETHx(w715ZbeqPCbBt}u zNQ|(0GxlC=mOHz^PP)rTqg23QkO9tIsy_`=5BY9Z3yg9ufmPOHXls}x|XOmF#+1CZ^N+a!KTWV2p( zs@*SI*oa!lu&b;kXS`YmF5$I%`ZKCj6!9{l7`QX+$m5Pt%fhUZi3uVyCO1Mj?+44P z%qj(D>0HApK5Nf6KY0VWbstxePS%;N+VbeM<51>WJc3jjRftelbS5f~x=nL%hIGcg zPd1YqVT6bge&xEn#ZrUEd~L^Ji>g+XJ^}z{#2*1Fd%`bfY1Ns;J}@{HtnYP&o^m97 zB(O#a$4l*PZzXz!r=4-dN=;3Al9L+!++dDqVUwgMZ|H}Cx;SoRu{^S@i}^N%BO0sh zC?CP}CC)_lQSfMdYC^?tsyeKNSIjPzZ_J~KX(q&zxDoVmTbzl9?VM5OkY>`7?&r)V zr}g+V)~}!MV+9=N6$rsQ(5vP!io$aQ_0kr2$}@oBSOK3~XcN+uR8gk@p9SBwBRa_A zjCIgb%>|n0k?3=8YEP$6y$bEv!xd1~HRC#xHMu*HLS8!vrE|}7X26!R74m^nP&+4H?z1Dh=~PL5Mb!wvjao5ENY&sTlUp{ru64%1>Yxg3)|vw@6F`}UpvE9AQ!w+oZ0H~4 z5eC?_kda-sOYW`pId>VlAX{N}c31H~E%wpvU4iLnpOh_vqUByK*qE4lrXL4%o+Qz3 zC_|IIh){K-+e%sK=Q6G8Ga@6)F>%x%y}P;YymH@BnT0}XT&{S$(u);W^+T60g5D^| zF>=U&3_JKn*TWnsf}6aGo}KF*dYlZ}<+FX})bkR6?jc&&Ii`>1A0sg?g!$@d1;#+d z(6i5&;|wsgw0Jc~lr~hFN{@i<$X|)5o^l5*hi74l5s@I}rXjy)7#%t3yub<%x>VAr^+P?B72)oZRr(AtNMNE#!%70avD3e|!b6FcLcm6k6pN9Rkyv zap%?6K;;)8r%>v^4$|zYT?XYHHXltb`_Ph_Jt5q`Cs^s}5lNTs6cwDNm{T|A3W2Y^ zF&6N@Ag)yldtL}OUhn(MdQJeNPRhei90u!y8--M@oApM(YE$Z;h6;7f#US6zER)2i ztGYI`3xIY(%}NZD1ak>Bp5qajAFzL|76e}0fh1rcAX`u%AhrMPYO%DZ_i%7v{%=*I z@y{bAQ$rI|Clbd0uv06^N&^HDeRE8h$wpNVUu$9TU-GHf!Z8GqNGTv0yUPFQaVIfZ zo}a_>*1R=6k$BueycG>+N}336YlD|wE?0T!E{pQ^@$dn!4LYHTPKj%T*JBz==66@s zz;}WYtwvBE>Tv%zvpFf zgQV=G$kOM?|7umwQoj(BEV5D01*@}lKLs?sBpjTU-fWD$d-Fx8(XnR8Nt0$P@J=$v zxxCB~{9M`sxh@tKK>WmbVFD`ra(?Xe6>)zpg;%lQO51Yy zWpR4uu9=%yH-|I?g3wdgquW~t_~jCLBLT+MOs47}!asRQVVUN=sq~V!m3V`_(jlm-Qd}rvCv1H<5-2cUd|X{v+>+uTO6eX!-%+m|m=} zP(tAR+m*0%J4cUhW{RPC^S&pvTGpiPv5huyvhxqNRY$8FV2Wwt>uXJB&_maonDvLv8(Z2@g z?GKK`RE3UZqLHD(_%+Ssr7KYOZ~XKpA%l@Z3mFX|4u9hqzIK^Yd}DHxNlk#`AgWdgx1O-2e@~!K2s$=(E@8{O%^b@}K?}#%!;=IjotrEW%q{T5lsfE5b z3Q>Ynty-+3CZ6;gRnxqhgZ{IBzQXE661XU0b82%^V4^j+Oo;9%YYla*;bdNb+^l9%NOnHR($9%bi`bcpo zJy#f0a>#K>Jv_^ki#|L#@RvZ%i>WU==e{J z(Fcparfu#yw#Urxa2dIjkFg18*`a2Tv111@{E2zR8ryH&bzM$$~F=wIhW9XQ!NJFtZH3Lc~gut1ukJW>d?bo*(atOshA zrEfhtrYEh3zqA-#YYDYakDsaR72bJLX3eSevct<_JUVGB#+30QOxhAm7O)Q;0UaEr zWlCbuEM6o^<}PPF4KBVsc(URnB=-Gb4zVNqr6P?@TDS8KBZ(?3NOd=IBGDSIEQ&oXW#(?r2OH;sz#v-Xgfyw+P>h02GytdBBJ18FY< zT1t)f-_1vxOlH4j!Hu2i~@g$%;nwGy#<#S_-6cfrC>a29#xWQ4Ks6;vlvW6ff^e zBlcAEe0Wj$BK$IA(u&2Xl``=T=SpEJV~U_kl%u0Pi>1g_&|o6Bn5MO`YArxMe|;lG zB9=3=hAh)|+`_#Lsi8P0QCLfkRoaAhF)5tr1%QrFnh8*1BNu)(QwCL4OVVzrTjJ2; zm`Io7{}5IRj-!q^h_GxaL5-xT5(+wvtL2-lofO&6NX|}=41E+U^Urh&{$rfl&NkG@ zxU-lQdI;O|Da{}nF{(&@WHQrC*0yAfu0;dWS#4Pw^~2vX*I)r6s^h5X>x9ZppItN4 zZEO_7rf>|?peUvlDMay}#-_@#ZO*|$;gp>yJD<$)2|YB_ob6YQOm6zBTdr0^<$KI< zZcdO?cRI8=soD$am_4C;+eu}*d}S^BL^dQQta8R++H7ZCItQ2aCVjJSX6XXutIJb6 zX8~ioTprh3+AwoXfx`mt{0q3KKm{q{iK1wzR%s3eUcNTUtB5h9ifrxMa5%2FYDK@m z5dzT11g^UUzdX!G(cp#JxBcghIvtwo%YtWw>mG(htt-KaVe?N`dS#rFYs^idH*4%Y zSxOgcth3M|{zmP?$bq<$@UH*R-tf@U0>{AWu&B-ZB2?d&)9<0HhTu*VDzmpPZ)Hor zuKm^T>oX9Ro8xJ0UJ(RiQ-Z(2nOVXK5~A883neYv+btDKQ!8q?3ALCP2sSZSiAu+` z*!IVK`-}n}P;Es{Q>d{u^LA^xrxY-Kwf7}oaDu-xCU%$JoO%P#-{z%cQ|eG#^-J!T zzi3O7nwoDBOYjYzUr7+7{DN8L9gMZH_9_A?UFhJyicdetDr^c@ST(zQOkJ)AflTdcX6<=#}V4j{Qz?x9Co~#o*U7&-8|^5I=H0r#1tic-DX}yf zEIgk@wd0*klM|*Onn+P%8{NTK8W~M&uLhTwjE;FH)wi<7$Ewn~_yYyU^WI+39N-0j z3*u^LsIQ*$;rPbW;|s#reZKM<>Wnqw88A=%i^$0t;yR^fh}?9fTN!t_YZXbm?a+vC zvc|0m_|nKBOk>&rEG_R9U9EzkQu!@#Id0rCK2Obr-Q13nz|yFE%XVpbI+-Y@QpK%( z4i5J5LrVQzkCS$mv}9AGYbH$);43pg$^v&xfd!+mpo&$x(n|A2T0<;?vop65NlrW? zt4ETft$^PZ0W*g3al<@k`{=^Dsm5agqJ4{dPUz zrqJqiOI$801Pn^_0!WWykf`nbKp}ssK;qO6hyd`(#;Jr?urPM zG;d-m)u|Rz<4$t>not-_kT}~dA&05T37I0O+@(k(f+nGzjUX2`7v2TJvS3^#4Q6`q zOCM!~wb7^1MCUfW(@X|dH!2n}hMwjm?b)&gkC6=;r`!>miAY_yV*=#@gdYu~bh4rn zv=5V-@^4li@>wCyIdg}Y(^gXkvgr3p>PS9D}Wxq#023nFXgH) zs64@r$YZ(x#Tk>J>B0j0xl=b-9yJXgbqPt~eSn}7n9giGH=<7{50=`<(V#O_?sD=! z%i(xz(n-k^rl=B3DAt5TC(u|q}yQ9=A-DEdyf0Nq>_n?w^|VA)cbifot4d*2bnYbm?_XrE4C}PBd#- zQzVcwDP3N|hk09%!ok+&@BW3>5+81`>87vHn-n|FAExhbOM!b3EivQL?2b$ zrzEwjr(5D_Wp~gw1pl9O6n~XKE4nu($P}{yZSw*BQ-N`>v&QV!dFaj{wZ)v)3UftD zGyAbjMA@OX%@R%8*7tvl1r^auu7It9*@$;%u2_D+t$Df|_6%bEHuSkw_lT4Go~6@m zBj`GS{MP*nqK#B}cxO9xRn1uKm(OoP4#2NGT=wh%{Bc49^6 zHHK}`SFJ$1(P)2jD+m78VIaJ|9Oyv){6^r+XxfInW~Q`fYI~2VAH>fOQ>p@j`TJ%9 ztiw7yLzZPV%gUMs744FWR4F4Df|ILsdaSgP6Zj3wig%uNue;iSOml%g6!3B%^&0If zf8}h!=ad3Ghe9m*0;V=dinCZ2IA7Ky`o+-k#9eyEPkgi8vD7!j*00Euxv_=V_cuL> z6oCt1OT`%5|63Rvmlv~CJoQx46!pp@Xo+EYzZBl7)E2Woy6JE*#405nYkYA6-GQ8j`2mjLtvjRQfe^tCKz*E!1E_Vvo zC209L)pU7SW#EjvbLVu&mDWI%E<&6q^S0mvn`fB&Q%&fY;sfvSRqE)U>`1Eyp_V@< zdm@$yLg-qA$G!>}VX-~B`0EJEF3B*{=+6{5&K-F;-J6hPqm=uX&3W)8On6Yqo}Q}= zps5ToR|Hg5WSGxO<;r5*XDoo84)sFYe2F7M;#>LC#w{3Q)+9T3F(_H`^1|zfGg!9q zF57umZojB-^BNw{x}7sK%aA30I%C%@+^|BX9Pk7g&1~2Qm7ks{#HO+H7jrqBilB2bM<_tWL=Bh7 zFqh$qkQu00Tg7;T7HQfPn;_1fgiEWLV<}AUQy4C=Fp16(f{nl#?S^^fQj;>;r0cL8|0b73U+p)Ucf1P6ZeZ)XUlu-UyQP zMGMTRe#5PWC+WTo_vA#r%ojd;Tiz2cKPSn5VHSU&5os*sD-f#iNl1qh70Q%3{nIn4 zfW>nV>zASDtSKNhW2YWEa4(rspir~d@)zR7Dc(9u_H+=TGnn%qwnRN!UQiDC!09o{;uyc+3 zAS)cG?y0J!K;+t@U)}+#BHx&fCnIg3W@F7p1hf!BvMqF9cB8SeQ;un!x25X?O0P}L zLIqlJxHZEPw2!Dn($$?=JQn#N159!L&d;iLPYU)oMd){yHLgY6i~UtGiiBRE1Acj`_fk@sh z{|#D&2%I|^{2P>(*1?3-3M-kC49ONCC@KY!Q|_Xef?TpbL8g_jBNLOZT~TbAvmotg z3Zq;2G(SB->JsNfd96rSbeb}GPJ3+SrQWepyI<*lp}p3Rp9%LGC0k?Elq2XDCJT7j z0LF<1b-Q%$7t$`#*T}I)GWfvy<}LKaD;F8MNxj#R1k;~0S#qHI&i)ZuJhpf(D-;!R zJOu--i7k8o-Z4b%i$Na_e#3(~NV5&62Vwbe2*<#MKWIE~Q$#PS$B%fG4jc8Bbo3|( zj6En%*54Bs9{i4xdPxWf!FxMK-r}C*L2j=#r>vao_=b3e-+v2_D3U%{3*1Oe=Jr3# z>38II=*HpL0mZ!qjYUvsdSIv-`Ffu)HlgV9KSXiKX$-Sd%q_N^PS@nJ<6LWXrD%SPd5qE{#)=68rvWHF!K9J+fJ3UXe%%sG_c?qTL3ey8C%zeiHO zd)Uh#G>k0jtL=8kUZP_-rR2PLdC#O#O8$|CC-f9b{-XQ`XDh{>Qs)$R%Ia=$oD|Sx zwVg8Bi7=Ot2kK6-cgS!vEh|jxqK0WPZ@Uyp|-JaggL2UN^ zZ8+#>uy6mqT(!+yQl?PAqr}Xq(?$ z&`vZy5&>2HhZS{%bp}EM#epC&@Q-5R*mn&0`}-E4_#?(VJop1B(78u7d69ePkhw_Z z@~*Gsi(Q@Gi69NVK_9`jnw`9*CBCc8V_d(m;nP#+4^5gvuVI#4Gh5H?(I8n_5uk&; zvlWH+9{3j7l-{qx_iyIKX@Yb)v9__7bdz?a2kZImyg<4>aNT7VoxRMq<{CeO4Xv>z zmt;2Cb+p@9iuQ0?&AD1rNpDllxU`7UHjAG*Y7=PcJcmfIon#w{;?q1s`<%IENM)O5 z2mP(d*F_B6EpvR*vULc{GYpDvxz0Dy+7EVnp$yDId;3>HuE`OfVTo6n;_hOv7qmlJ z#-6*&j%kVn;=1j%w1})NJGxCRhcu~m84V%Eg+~9pU(p2`g9xiifj|7FyG5}L&Fw)Q z_E<>jU+8epcSu;8WFHFy2^Y4*Pi4 zq2xuMB?|yKJ_l>q)1|@=7JkPGeoYCGww#wn-ge)Lh0H}$;DXXrASkpXzcquElL|0k-X?whuplq*U}@xk>9$e zf=p(sS-e8#toN&swMtFYL1zRt7v-#j!q3GDaD&CEn1Pyj>>?6zvuq-cYCzEWbu!MY?_zOKQ=!m}*-Z7HY9rSR755DO&!!V~QZZ@}akR3n0Nn;**bk^l<(A-aQO zA6k~QUTY%RF+5QX-wV2DU{C&s{X*JZT8+Sw8EFYvv2gV$-F0@Jp^J2U^_n z=tX3BFk&2K!-v6&mPj-BJ)HR*VWfhv#X6#Obl!;RJuw|dxsV22$S58Q8PbrPj_|Sz z+zp|U7u0CZ*|09MmUO)(m=;Ej%Q&d}{JkB(9{Su?nEhMTmfSLZ#f#()k903D)!+Sx z-62$G7_HzDf?wp2Az)W}@70j^TitfpxB342m-!FN-8S0Yw#!-$vX491*NNty^_vl8 zz)zCe+L+20H_e8E2u*Oo3bTd}e3d40mr|sL(r_YnvWPTjP1S^!dRj|urG>8Uyq4OE zmfnh%+PoINMGD&~WfEc{NwqL9l9hg!8#wtA99VYvGf9h{NMc-OA3#{$wAR-j3w2YJu zH|nR--%|My;*^Pj(G;Bd{%WOJn~NtV{~8ZTKw03#wr6Z)kp6e&Plev9LNX?NsR z^h_2$D+J=`xd-}2F}wz^Py!smO?fAvbB-v`VQtS*G)ZnH(Zk5BdZ$FM29 z25f804T+o0&Gw3MDufC$*vx@j3PKMzm-os$hh?>}PMj(61WLG9i`%e%<3fdj#?^#G z51!sjsBgbVp*YMJKi7da>6^nc!x@X2M=Idm|MPUPYY%|r`J19ASY0gOHF~TttG-p$ zg)FGxM65EreOn`aRVqV9Mm$=?qG&=vLKys16cuV4-V+z5&{FMZ+BwCT8_bF{25k`b z@je<8R`dpk^C0wt&UIPg^FV`)%tq$+Hh)%pD~B2!g|)+(PiQvZXJTDH$b4?~ml4Dn0$T(1B0+C<_oXrW8Y4 zC*rtqlagJ=DF~x2>LIz7M{yG__?nGoO*;7#3!z;n*$*{(fJ+RSDht|LF}3oqg!w}< zzQvXaWf}gM710emMX;h*qi+J42)H(y( z=%;L|B(1W)z^U4AfgQMHj&70zdXdh6D!fCIdD&_dxv z`(~p?my$k~^Js)UyE8y3foPc4gd8!qo#anyOz zh!7FQJu5qD@iF_6=k#PtzpwB6SAFO-hlvR*jiIKX)POP^iU!iC0%L{Z0%Ev1RcVO6 zY69xtjzHGXv&)C79`>Uuw_P`^r^wTF!SQ2p@fV~av1J4;@Sout;mxzV-fOJXOU&9` zD^9&hhV3Aot|M;d z6yD+>NrFLoI}h@8+VKazrIcAC#%RrTn{AbJXUq?(Kq9@K=NtUP>h+*0-unSnPdSuV ztdpaf1^6F%1Yf1M3Qk9EkN^%d2N>8URN6!gaU6eN!6VoO^GM8-Kcj@GHg}2GQ6gQSpMTvm%pEac!hrH(gC8~!ph|*jt(Wrjr>{rDGuY+&=KQY)o`2!~ zHBVEPN|y*=KtMInKtMeI`*{*GGr`fbK*UBrZQjzrguHEipCpb7)#7R-eVuK2aJ#|?& zw@xj!ow<$}(`C`DWsn_I64lTi z<>cHoX46%(Z(b)X7OEdBxrXVNKLP30OVD{L6L%Y@IkH%5CbMmMZB|=%v?{A~j;a}4P@1Z- zQqh20SNX3=p;zTKl>)tqH%S-r$2!&U%_5rgtV11}%&pb~u{&nlpqKT+1}m&-^b~`# z`J79RQ{)$y&L!j*_byL31#NnITEvE;Uzx@65@wr(rSowu4Hwq3thCByT^Z`sEZ5#z zGVHJS0z;lFO40x~K*+z@VvN1KB7~i5<;}VRN#b(Q+SFDo4ZKQ?mm85a<#sbp9vgdT zc3!nVl?+-9Jq(m zNV`YbEx4uDQY2dGWR$K8y3eUI*5LQt^I2HO8aRHquV+oMa zCA)|q0KI1@w=JLW+^Yy|A=amp&_UMv0tq z=u(k|1a9!G03uRTmQ^TRJzi(ZCjPjth8<0_DCS#c*bu&Ys@vrEH~r{V64)G<-jWdR-N7vUo+P4={2DOyOH}0L&l5Vf5`m3o^lB!&4)4w5YQMT z5D@LZ1=|06E#1UK4TU*b_@SqQpjB4nm~a;`WcMI){5*Vr*#_BgCVKYUocN|(*!UtT z`RWzx>FyE8wmGX&G zS3l4F5)Nv?xV03W8k_oc$q%`st{AVYmBXO|HY>`gTJt5e8Jzb!ifmi`D=tO>62DRI zmqyD*@Ov8fg<55m3&K1rj^zauNKSt)NY1iq={HX+Dc*{bZ1(thQcI>uQLun8xq8II;>YRvmw`-235po&jy9-X(Rq9sm?0QwH!4Q_Uir^GFK_O#2>)-JFRCxHH48UC& z-yY<>&mIO$_Sx7P1h*sim0)U8OLM*9H_$B^(rEGF$WAz|H7fMS$@c+}>opfnmrUqQ zKhf@o7-6$SLiChDB~`}Cl*iShd9PR%KRLlXm+CwXC4$p#za}9Y94<_{MSk z#)=r&z{PLS;$eguZIckXuy9|akU-Ug&<>>s3ivi0YKvqYi-E91yN;xnv2JHiHXIp; zMZzXxow3f|3Tc0|jS!$(oK1ax(6Lha?k8WufNmi(2_BVyVe!G)P43O|_KgqlOa_nO zZ3S+}2ij*^ozom;_iagbm#pUJEjUE+F{CYu6{x2vS$DLrzCm3rDvzYBbv$u`oqCUbwZe9JFZNPtxj{W^dvX*+}@rB9>;B^J79vir(`oVR<_ ztcqQJsu4w4GS)et9S$Y zUKrL>KT2kcjopSt0M^ssh28G&zR@R~J<<+aqF?L&RMxkIEk>FPtSuwZJIXckSLkd` z-!%JBTo8+>gAxkypVg`OSe2lh3qhYMM}xVeYUh%AWu)``#P_g8#dg@joK; zpK6F?DsITn@gsjW(SS;X`M!rfgHSdU!pq7QkPD(vptkzz0kBL2RabSzIL$_nxt_7z z_kzaBOU9ppcoX(kh!bW}!?gF$SK{lpUM8n5ulV?UzPb9U=r!n5!+`Bggy;(PexNeS z01$c=Q>fucxS{gJpPBX4Lxu#$#l$3160ZXZ^i@}=o6(deYR{iwyfDTlDZva(>{Y}~ zM!!ffFio5kT(THJ^J`%NvZJeqFe;2~BRXhLO)Z^O))VcKmL*NJkG~oA_wRxG z0?RwKo}CPw1sYnc7c( zm!X%jpDcsMM6^C*GK`fD_{Xt5bE*H@=0Wy{SxFjdfb!LA{eJ!hK6>JBZa5*=*i2=< zSqT88)K8ws%(F_my@`tHR905J+!>o8lu12p%&K=IFu_=}Zk{!y&R_uKneD8eXQZLK z36FM`Xk~)3RCB!YJ{=cUs_r*;fI0ibekxclZrhr*ifirQa^Y`P<`hD z-h$`O@dDB!)<7V}C~md|r4h@~aCQGY7NDz?l1hwj6!ZS3&J~5Q8sQ^syAO^D%r3Z> zjHsXQ;l3_>`q<$`oU0|u_kote<~a^$YRe&2+b`PCFZzSPOYohzn<0%gdRl7Hc5RtJ z9kBpgkQNThvCkQvMfdx?xdLW=3bB@K%Y|Puxzr1CpmTf!kaa9A0sKnraH^azxR(fKhiRw{8 z&B62{-Q79d!KfE4C4x&7RU8*e^)Rw@GLLWXx8$nO2sfi9-WHAGn_8;FOfHwE#kPjK zp&FMF+xOQQK`;xSDu`n8yl&ypd}pCjp7+0C*J1io4>C@0xDQ4 zM{{ge=_N6Ygea;?Q^Rig7nla>k|?kW;|4PmRlpaa7olEL24l>34f@K=FiBS>a6Q2; ziBwCI&YAkLHWFb=*y84K$*hYv-ma&v8+B$KrTrBjHR<`L< z3OflNfl=l0ROeZRgJWoZ`WQHjote)dRuPs1)a0hsWf>&j$PNt|(BtIq7U6QwQQqdK z@K16Z_O+HnP|{J9nr(e6aXIu^J*$*>e~(A#Zw`&zkp869r+NJO;Wd*6B6o!WCvN24 zo_(u!R+$tp&s7i$yF8p;RBFjEjJL4xi4&22nbg*yX3wVO8l{?>k2&JVGO`|{7{N7&B#mcsdSUr34 z!$!wP&6<4|qo;PE;w#Nb>`YbP^Jnc+z~Wvz_1y~)nQPC@ zvOwqt*UyR#l=|W+(WSEx*jA6`FZlGrP%nkFzfNh)_G>5OKU)2xo$DX% zTMq)3Nu-aR1_*y$_66~K?#ExZfb)dsA{ICo&FVii)#oD(nV9MKrj)jfB7KC$`|A{* zBvN{Q=!Zz!G6AH17tuf3>Hg6U{*QJaPSjeCwB_tS|NiH)0r1*B#Qx7yamy^yM>hXu zZt3%@xPI$=^w34TS;e8V3LrJbbMABq_=41TDP=ipFg)K4)wC9 z*1sdJrQQx$<`$<8f5vwXBuyIN4wa5+sWm>~8wM4Juz0uuPsOJ&HYudQ&4tv%0VRNp zgI}bO7V{?#)Vde=>p&7MEap#2d=U@>DlL``Cnyp$82R;5fikl><3Fc>8U8!{YlA2N?~VH7$F(_vj>MTpqYAWnM+pn5xfGG0(Eb64 z)yK5VSS=4~vW7kObNqV+=^*+X-gY$OWESz@PXprC)JzlSqtw=w6`QTD3}Dxgb}-Fe zbzIg_x4K2x^%}bsUnO zk;{^zJ|v8BLR?9lHW~)BFaoD_!(pEMzTAjxrUI%3qVMHJ;Qo4zBtkQ(k#B^Y+g`$1 z@{(_wI5%RL9kx~X`j=g~goskYjL7cps4sa06W*8#eAwzU`d(f$D%%XYE?iF$p3u3^D`OEaCRe3oLl-yg_lV*}Qf^<1T-uf17& zB-6HMeB8oGUG2H$Ht{6vu9(;-=#k~5Z%!1YFv7azo!*FchG3$TcAM;ubaH*V(#Q2D zCR@`|>#`KfhAIn(vk=$DUc>vm%x7m|nxeil?o*~BVq%rAm^or}eC<dS>%1aSm%sg3EC)4)G)8>JrPyutWigZ;M2(aJ zpid$SvF@x4Ql21-$M*X@tPXNCMCLgZ8eVY^fS}UG{T7iY%!WmZ%SUqo(eOCq`8Ei++HX%(i?KB~11VLO1GsU24030vu zSPhJ|OWH{jKxaQd<~aud?&I4vf<9%<_LDk!SjzrzJe6bXHPIMxC{B-bDcP%9N_D}}F|gsa!|bL48g(W)q>@Dj zG8H?KbTyx-!lSyX*pqe7nHDS$b{4pbx`S0HsQwUG6<&2Moq!RsY@|x14YP6mR0dwm zf5Gm+!x=tv;7wNK-QB)^+B{b z>;StkQ{_rQlqoXB?!`fvI0RpHQ0qIuog_=3-mYJ~7hA`;tiX(-P9+V*P;cK`Rv}(j zx1~^?HpH04NUd}71Dz7>uyfmLruy56bD{ZTUTET2NfsGL-*DH{aE%@t@96YKu|*B! z!e#C%Lz#4mv%h(Ebeg-40e#|T;XBn~cP1?roQl23u- z;+(_h-E&Gekk^)+WPmUo;GBK}8xtdPaGb4%$X*_uAU!f*@6TiF)|xM{_4KeUl1tpa z!D?oa-3PRMy-qBxPZZVk7GbYIh6~>f8FXr;%rF{E-HM=dx$dM_@WUm!F>+!?ps+I( zYoSbjAjY^})+_J>)B}s60jE+Pqclf8I??tEQnV>CGSL<7rQ8dY-lH-RX29?=;0Brk z3C`5+{b%4xphY&2g%4ym;yp6%;3L9-KrQl)JXY;-HAnOsmcid=WpN3kKmGz{_8(yK z{<{*_*E6vAABedY^@o@|upl7pXN20Qi)*J*z~&j~)p7=`gy@9H;ErC)#m2`tnCaGx zFwf$=<)I9N=itwBgK4q-DJ7xA3JXqU<-e8`Reat)4_4CgYVtcbX#W z8Q4wsIwHeiJTA8@Bi`+jr!6ZO=r#H!z;&gDYr+~yL>lp1(eJ-U$_bl6+N z5dJqWzZ)aG=8^1uNDP4rg*{jLrX&5{cl@dFHacE9Top2CY-lhvXar7M#Xg+By-iv6 z!@Pvaa)=^pm-E`)xaN9@hGM=113>C%3#$YGp9i}#LF*`h#{EcXKJ_OnW;*yNMSVgI zm|Ij2gdI3?U@#&7v`4k1H3}T_d?5Io&DK@>aH-KIrkA9T?|u?Pn4+*G2w-$JGiB_z%|Ne%ltD=^P#_jY1Yfkk zBAbpx8Ay!lj8A}5WtV;h77z7g-A%yeX_H*uD1ZN(oE$q~QU0pLunqQa%+LIfa{4c1 zN-E6BB7a)zm`S>-W}6DcLImmOb3*|WHu?5RKI_jy$*Ah_`&aKY?|>TZrEais!(=#kB<0f)2(a=nIC3L$0tF z#kq!LfU<-V#6s`1azFR15_H^DvjsS^~aJ7UZ`Mp#`|f73XU(aU_R0g(AOUF zdHU9NJXkLZm{pD*X`iTTt!+f!%Y+$FnU|Q9yvHBPa&d0}J0)#arA-!TNd{$$GqsiG zRjor0OTtSWHREkVUSm#4p$ks3(a{-DA+=QLVYT7}`x&{n@C=>eNzGJeg^cCr|dZUFWruks!* z!kCH{CmA+YYPp6UpF~2JVJyu-psL}NA^!+6)dF(Hq?n{y>VAa+jPIa5Y1_F?5+c&% z$r42f7xJCU4wzT@tjX60{T_;*pi7{g?w~;Yd3Hvlvr1ivHPC5I^ zWr0D1;1gK=?KuRG7f1v4-QSY>F1C^KoE)t>uW!K~j2t}je~vxa zw<;R9xczp(V#cd_iXza%{8VEaVoXZ`T{t9U*&=!`guLjWg4N96&0r0Wl{$Js&GvuI zX6c78d>siPgCRYPGYnIvG!x%dS%*#4K2z+L?+RtKXB~>AGQcSnePAB(dXAgKe{aQQ- z$pnIhHy4IFt4TDd+ILX`RWA3C6ex}`?^%kvSI~X_4DX$KbWNQ1zb(E`vgI0h_=DYY zkbhCJ?&!fY|xEBm%&X}Q+YW4rx&WrQ8U>3Mo;dVEU(C(@gF9R#t#|HrKE$O43xRLG)- zoN%&+cerxsYhiCxnyf{CM-ZKcaDsdQ8op|73&a5!PE@f0<$G<=jUEI{)OJ z1;OHCwdSz3TNA(q19y?NlNFBC8~e+x3RRbXxY3(SzboX&|!Um*fIiR;Kj`v-6&<+lXlhmoevA{`cfFUxK z-IxJQ^m`J(4OWJQnjXEqit61em@PeT1b%F-3dfQ@a8AJkCf2H&5dAxJ6P0$;>07T) z-xH3yIBEx@%VUepn41d&BKC4%ES;GZl9mm-@<=Hy zZc+hN6Hl}Gk~%M(<i zk?J^nqErm@pS|5o)L5!Lly>DIAIg!;O&evR3OjFEQ}p6eOwyqVW|SpS=BZ&Nw@E}S z=TI%i_`w|jClD+#Q&($UBuM%Cr+WQi?eva;^xZn;dA!bK=29~qdg=#9UYO7>xJo^aGV^R>5@3jzvoR(%S3*RK4JF4 zMWHLtCTm>Zj?QdIO{eH$r zGGK5&=Rwp(pK`8T$7W_cGi)01%Lj~$lq`^VB}E;(kETw945-;ISOn0HeoC4x@0c>U zZW3tx8$aWvfD*sbHs@BP?bDS}{vCn{g9J-*FihO)5%hJUW$k$)+e91e2Rqd>EPVu^%U~Khf<&cC#=L~%T4g&Y-6UpQIA`?3whvUE1 z=;*eoSRDWb0_uVU0+RZ-!bZv3!O7Ov#@^A$@E;K*Xl8Brr}6(GgesNK6tI+#zpNlu z;FAz%fu(7jlq?~mt?^8)aza7_XTO)h!f9l)?I0%6w%fS~wm-RJ9M-guZ~)G|#% z&~WZOuXOeB_1g_DI@kb{G7A^)5w{*~I!y6IZ?zune?A@;>i}g8BqLx8sSl(hNa4@< z1Cb8c%E2h;X_^lh8TO^1I+FTRxt62Y?3q(V;V*@$jfd)K5BP_<5FYb$Mp*c3+Xy3H zmATUS({|9Y<3UUYQ}RLuggR-%fT4s#2_`8}+p7prpS1}0)h7W|A}aPH$*1=@jaI{p zw2&F8EF&>c>%&DRT|z|}X|!7v?KQLGn;ygXSJ-F_(h~cvC#hG*>Dn~~%Di0~>Ka;Y z#s-eVbFWBT%otX>VE+~2b9jiX=sJN$K5)%JUt<_?(-7PwtZ z)HZh+w}I;qQ!T=r5;5+RrDb}AA-_}A_A;_5uV6Mu`Ws;aQ!yH(l#`65)VqL8E#xFP zpOe(9I;Yxjvc9Y-*%;?H7?|(qeE6XH{v6g*zMfz?jE^ni?UB8UWK`uT#NR$Z>Ce6< zRbs6ac7si8y=ce!Nk*xdUT1Y#M04ntF@0L$(yk%_*_jkr*K=53_?zaaz86-W5J6F3 zt8nx|1%8CXsJWY|$d~m-$KF9+b;cIB7{%~2+p(P7Toq8d<93Xx-5rjpEm-XjT|cHd zWyI8%d~Z(aI4YN_wg}LEe9p6WZ@YMYt%Bs~%9Vi@jeEV|qEu#H_btp3y)_@8T;-~k(lkjVYztb$6PQRE%CKYel4foazJwK zTRm-xBoS2LAm~ZPzO9&dd9*gY?cdpWy(>VE zlYOd!am&B~{OBX<^;eKE2}TZ|Rt_YCTs|{&2xDRbC5j{6{yX~zdEYTn8vZ2b3~65Q z8y^2jG#GB48B))upEUCmoHgNn!2F7g0a}_FcPM_Qb%22LuUxER27b-XJdgl%;C-oO z<$WntxM>dlwF3w`%1`uuE@5@#oycCXXo>f?4?aS41vAS{k(BdrqcK*(Z`?mEl9F<* zOre@)igev=vA~f%12mY;RIaJ=nE3MdRzdpXdR*z9ZJ~n!O*0hEZB5hCW2XAh!Dt~E zXyZik(sdl0no0%X7-kZH-JWlV(LAC;+zmnb&`-Euv>Bn`&C^65txwNXesZ$#AcZeHrN{-Px7Q`fNTq(*0B4XwV>^u;kK?EphiV-}$1z}4{5p(Y{*k1wKlHWQA z{A6}m@(?(23x}3kWyiMu8J8quW%o^gFiG~uz6$+MxODtS*(W1=IsyH^cCj#Ul>Vzp z@juT>nK?KbS^rh}-b&qua+%2>+qkFA?xJzR?5*@1i4_d=ERB?`%^d%$zZw;^Wajyid0g5h$J&6aLUf+L ztpsZcP`w%|Lqf&zL(#Qcx@IQXxk$N~7lA;2k|B99-t_#Hm) zSdUd+{Sq(Q!0eUq7sp&g-OmCLy@YnUcqK0R)@b40@g@l)8Lx!3R19cI({odr31iAz z&BMSG-1>uWGGy2ysThFW05K6p>~N&gK4PU@7Qv&d0!W=9j=lcNR{5@R5z6K`6pb!8 z^URZ`#kN3oPxB4->Wvkn_Lmd(N%>yS_Pb&o!Omoy^q-ubT&?L#vF4` z1vo~cu=BRr{5B8)V+_K_I)IvJ@W73);`2R%oo$<9^StQJMW^68EA>xY01R`M0m*Ae$Ofk;CW_ zb@QMd`Rn|%WDu54t_J={M)`kJGK~Kz8O4de7EOGTI_o0|YDkd#9MJ8@Aj=7He3#9Y zogY2mpA9)%-5_1#v@o=xN^}wQM?wV0^(EV(fUi$dO7w3DRA0@!8TZ^ecQtwcI9jp+ z!rjxxVbLtlbIrixt@3Eu(TkP!$ZKGnf`HDnmB9|fM{q~JmoB<5X`aDBTyJy~MKl&F zJV*}^C$9GkL2MciHlvQq9Zv9~i>$&ZU+<&o9dDB`)bWZrGh;;nOfOHX8(V}9JES5_ zK48!^b8ziwr5NY)cc9&2wr_ozA(lWAte^X+*B0!|#x<;MhzMNdo1@iW_eoaa{56}gqcIyX zm-(H0oj~zX2OeOefTCxM+K+pQ$ohp>AB?K^W@E*&V8wU3QgtpZAmGZm@J$&nZ}d)a z9FY!=wkWbOzoCNQ@xS@`X~zJU zG&IPEfdqR(u-7^#8^#(CtyL<1A|cuWg@W+;;svF^Dl0+lBG%1La!;Lm3iN3Eun;Q+$l6QGD7A;n@KYVzy*b%gyAhnBPMligXY` z-eraD&uzrg#aCSmMJaZ$!|Uk~OZXfKFkzL=_X-QTNe0#BZ;n*5V}wR*H{^+tV&#e{ zq#_z~jVJL`{c^n=80ki_5vEVL6gwXoh7~+84h@-IVzk41q1eN>I8$VccBh;mrdsr- zQ{7J%JEk4C>;LU-kowz~mytH7ziF7v z7dNWbX>i%tCxhoCb^PTirP|>@hTIcyGgkH_s;G@CPk~oLy=z!yAKy8NfpXV}a9S>; zNK}leikZzBGXK>e19&uFDOJW%{p|?{zVRffoZzui+_D1&4+A@c?BER~ht^NN^ zZ886sw*F&17gBMpf|R--MYAA5U>vevD-S-HEM0+87zms=k*j9AWZiIW?1eJrS0Jbt zP$>9c#nZ=&{?ZnSVPPgm){4VmJ?_`@%LSKjuxb_{R8kn(RxKYavP!kZTz{sYMQ|q+ zO6fI%UdLf8lxGK&@SH1?Sy``ZrtAsg<-zn1o-|QLliP)42DNs;uqoPO>HM=o61^w= zUmSA~kx&H9guv?Zd50s(al;aHn|oyk&-}y?Q{lsKjK{40sOv(+ZVTZmh%aVR_Izae z2IQci79zfx(OJ1Our|BNsVrSsE3qIBrMwHR4EIDCj|Di_}hjU;x*Zdr|szPv& zH;bFj46F&o)I0m4NH0NZ`eHRQ@OpoP48VE@Je@STnDKljag*9dP z&nOy=I!anQNO6e5LH1HV)*s0Us7Sq;X(`jngQansQ9<;1O&PI9>h7t(is3#$GJoHL z?R^CD;_Nyl?4DKej=2><5RFD#)j#f-=&c@9Md_h(>rl=C_K^J%Rfl%-DGbBLK8nRgtvJa9MvyQ-|My`M z(>nrNbA?pmmFlm-ie-$cgI`{A_DuDKoFhfel!`&RtTszL;n>B$h9q&?rx?jy99|lY zVT_#Y+*sk09lpZs%h=O(bmlQG`7BXFj(=1$|2!0NuQ3uRcv%GuOvg6koN4E)*R2E7 zDVd5q=2u%WS{C1}c?O$Mu2YyePBmuQJJ%?=?!I6~hOIY(MF55GUzd?M((U9>O0P87 zr{%uEq_p-BRz5aae!VXn1$)3Ia|g`{B2Zko=ly0@ClGzuFfUcsJC=aULJ_0V*bF5y zEl^Qc1}*({2NNONc!JB;rG60oEfK*XsLiy#AXSYk)hjuiboi1eZo@izc%U#E&%l}mdJFFZk~6D9qT+Z&ouMJ!#WV|# z#0(F^*spk{e=?t*kq&#K z+kijrLA=zPb2Hw<%%FupyiHTQxrCTYQ?2t4E-4)0Q*uY(OZo8QVqWqDzVD-q8AU)H z-!CGv?ja(nVB_=pJ(JPb$o)Uc>u^!R9;i?XKTT)$km~0agU}Y zIB+ZsmRz_^7Z>?j#K?~bB&Dj|OD(=y_q$w_*Kmqqcoc=%O?IPbLhDz(}74Xc{Kue*`0Klwc43YwZznP=K?2B|`oeNIhJ$!Iv z*#(0Uu3+$Xd%vwl!?W#HO9mfv@~Vp>r~ZphXAVez zB?|ABrI(XfWhHcpA!*Wz5)|PR8WMmDCB!IFFPv+juk?D+E7djQ3*+!vxu05I;p zLzC2Nj;1(JL$CW716Q}J&2qGrE21lY@N+z*F3jUJ`zzs#|X6AJRf$ zl*Nfmw=vepB;f(BVsnOjzLcp&mbcR!&$ArjiP08NW-6(|;!0?i0j2S?4am*=bIP8w zlN1HzCGI2gi4lS*3v0#GpWZ(zXGXK)3QKMhCSyFfhS*!+j@?rGP80G*L?s3)EF&b; z5{bX9nMyGtKb}KuEEee7ixoQN!zULNtQTO@NzB!uPL)cmGZIf^#6&*-t`I-VU>R4; zk76!NNs^*)rk=7w6j9pT(4RR)$d&r|O?e$~6UJv`q&c^pmt_N0Hv_ zo8~M7pVrv28{ti_O|%;k&?>bYJS*B;3J*)nqA+$!T*fBz8*$#BLvaT$6~XZ{Kq?8I zO=&7vFV!;}rNzKiP&`XS;x<196Jjm(UKEahh_0*DHye2Y+XH)wRFXbuH9KVm@lmJ4 z;7C0f*SqsUtdDdt)sdg? zu$#O0A|;tvthL(l z_OQ9r&mmfgx1Zd-NefxJ`7UXe)Ejx{8ZUIaiNX{-lh}eGDPL+k*@I#fX>a1_*0Wg( z%hjmIwk#%{!O^KY&oVc-jDQ!fNFtLVAFePim;W=o>G;{6PW(F&s$n_lILuiP)x0zJ z3Wg->MMr6&dtoVs+L*&}l~DJs&Y>7vNlrc=)>8oKk2flLI=J$UCe*78NOipIr?kk2X1 zHhgj7k1S?>ZdN#2XAsy_-?Q)Qsa0;ShdUprp2FnRf5scjZd^=|`w!p_p}ls9T^?X> zJh(VREilxzlX&pQQ-X8iV(c@Js5|Y|gS^z}pccmWrLr7tMj+aGpc^H8+-TiqkOW&_ z067&Z03O<@eN@$nYt{&h!jcQAOw2!^U%B&`h^B8{p=VzNLJogJbJ*n*(e=s1wjEgi zm=m+zCy3u+E_S;0l2JK(&c(wzhl43Pi9aWTg;+yU0izP~_ktIKr>>U&)hCpdO3g@Z zxEF{{NyLL8>ONJ|(xS&A;qwkjh-K|fFG-+z#FEEoOZB3=+z{QI+%zrM%f-CApUkws z%uE>7vTylu_ff(r+Hx?R9lV3sjs>#pAWYRBh^GzGf=q+lu2SA%+0O}%pS4PSkBGuJ zu2>*}hXihrZ+5;vOk?gRwm(2L=e9yxU9lq?EDJt_T;~azBP-Bb>l^p2_4h?my3xWi zzR-Eqb+lyx+McCq5bnRcSfjyUO7XS{X4L$ru3BwY1#bB3fzVy*`X1@s5Aw{fcc zwRg#;wZ{}Ae&ia&R-=0nfbb#cu!RO^Q{<;7?9s7DY}vwe?SWboMDratKAI#J8#tz- zli|)b?JHz~=mzA^iumxbC(?m@^A4l*$?+5e- zM6Dgi2mC&6@jfzUC|oYpkK=gC_{#YD>bm;+a=083_33!y^$oxIBddEbyKjp@HMm&* z%OTR7RSR~RQD;t;%ClI^>*#_IUS+M~EXEKYV#i`-#flTYh;RUUP{|?G!bX-rm$95$-bd;+wq_k=3ygWuAuCSnCEH*C7t1<{uA?F2 zteIqLYsNU_d{v!%-BO!yRb6Jo36$cBThrXG#<-R7c%1=HRHB`SmT20Evfn9*@}PY+ zdE%;0!M zDtcUPL#wp0erN)U0}fL>R?II;H=n4Fz_r4n*Ra`^LD?DRssV4R_v=D|TW7+;W)S1JOP2LviGIfGHoCm1(@}ol z*D-)#*zwhwj?B@3;d7z;j;&m)~)RXcxEzBEDz! zTT?dwggNiA2Juk3Lw2@sUF~LaO}egLtMRmQ5q&zH(7eNbG;`hThL$Mj%v%>$4Mq5# zDAVaXIi?1gA%*FR@CL^D)n#kpI?_GHohQ&l{wgD)=+x1Tleb z5O&QSa}taeqxw~{&0rxZ>&G56*s089PPY-#O0bnNDS-k-D)kkXUlC+B0`T3}gz*su zwo{o%9F3;I3DC&nv7YlA7;zSUV zp{yO0a{5YzV(^Ur@p502Sw?`Jaf4OI2`8ND;-p&D1&qsd&;0T7gQhB<`3@(U(ku=C zIqMv8QM+?#M^VNu%}5`2xd?^wOoPIW?ky~4C3(|H{&WJFy5tX$a5q)i&hq=-lwJXf zq$sH>*`qcU!^}dQSeHu0aStws*2T?E&dr(jqIbda6sr#`yFx{REYu5br+!MqzV)yI zK8{$jn20r#LZjqFiBjn9d8ioAP>#(4AJl3^Ic)>i$CABt9=@)L5V^XTe5LCf=)gnV zpcJkvtLGmM`+Y%{7IFiR3RPb)0@!`R*euA(ccadsE<8|f$}hNmg)J4j3iGzoEJx1c zSONf=r*BdeKd&`Ab9(MwdZ-*zCva^r$w! zJ?xl|5RS$|z8?xq#1!-+ZdqAO6V$xc~EhEst!I*mfZ0Y8gAJ6 z7B#e+d5+6AcoP}>XY4N-T@vqGRbi+fV->6670B8H-NCHYq@XOICXyWQfio%nse33G z7K#{Ldw34RkK@9APxKCR2pLYuCe5aW6{nG}u4)V6Y70Y#i3&$0wTs>JA_@CA_?Q;D z=tsI3JG&Slx|sNV^0a_H1a-r&cbw&dvzql5@U-~#=k2Z*te8nwH@TS$KB zeYdI-iG~G?V1S~ z!~6pN+gfgoNjR9ll6l|$#mi>@J%9=7IU1Ns+ZY=CixI3)R$8);AKoi{@TWnex-7SP z$Md(#+@SJNVrgf|O&4_Q0KeZZ8zcp2nSMWfkkg3PdB%THWib@pygof;M?L=~N0XG&O;7 zdKP(PXgw#5YO$?@He)e)1DzIEBu14EWJx7EHPg$Al2a3-mr7g4?6~WOiwPCSGK*qL zBLhH|8Ft@{x(dw9IJ0t@#|E!kliGP(;&I;)YTrIz75eVP8Jn84YFpzPdQX0}4P3sY zGx>K#l75ebfU$D88W%xa!7#a@tl4#lwZN#aq8cF_M^m(qUl!GCD}Ucy36@TyVjL0( z=pFfAyo2@MeJx~T?O!)36by$y!eO zy>%WdT}Nm-ac6j#{l_ajwMTpH9uP$XrIfdHn)b7zuzBosJJVVBR1TPSTiv?0Cr7&s z`?-wnX=$%VaqZt&(-mz`BA$19D0VD`%Xdr#JdM545^U0x!@1Td@H!`M2ecG};`Lg) zd8!U%Au8%thk10SM7-_qd85D$4~c@hWZQm}fa4({;3AhqLmwd3y%tRK9t;%U#Be{B zySAWb_k5!>x0U^2`J~$&E`WWzT>~HOYO8ph{jlwz%}pp9y~~j6sU65g>dr$OO;_@q z7e+@x-Xz77bj~nd;D4vicKYFtZzP=O$I3I)y`fvcR-{2OCp*pH*<8zF{rEjXmN`xg z^V>#EF92iMA57TW7J^L>^E`^1t;Lq#z&bZIFEpvBubdGJcyHwVl{EVF^*E6-t6K&g|>tUX-?*lOnNP z+&rWqAkq^qi3_8fqg`R5nsBW)BaXKp9(X%c{+&K&Q%NGClztpr&{FK_iacH;6PrC2 zrs1Bjsh-=76!t`t2N0%;#yN2TE29sASbXNLKpmrZqM~JeNJ$OJshy-5Mkm)Q#g#`V zcZ)cQ7OQX(r$oH?#YK~=Faz0_uWvz!g<%0z`b-)4Rs?*?`l;gz*~}my31>xERGFB0 zsiTLW|4rdW2}P#l8S}1vNwx9;XiKa6Mwjw3pnBs(ZC$+kb}BaAT9OwV;2Wn?v%swJq;v zniNH6YAi{Y5}7f=T0C%;+N$(d60ua+6IKz%39E9Nh!1g=gt3uI*aTUWO zTZ`8?+?6}+&skwt7SG?jQ-pD?zyv-K1|~>76LtESo@)Ww+r@RS81eaSza{$WpIgI@ zn7N~M=#`n@5xZuuE#5_XT7bWm?=;sbdC=;W@3;^?ULEM4Tth5ggJ(=%i>}CQn~y3w z(HNQc8ex7C`#T$yi@lk^R+=i@_ygjf!vS5p;$T$To!jy^Y_L8X3%)jV;$|i545sCm?K%~DJgOP>pWT6Yi6f(jj`b$adOM; zY-q{E1T6y=cO&fWmIT+sHbCJvZ0(bC~=>cRqV}crCiE8 zd@i4A6ptk0PqM_^kZe+yk0Ph=C|<1=RS*${lX(e7*^+v~W|G1@F=F)9jMI6VWwk<= zF2$AJ#olkG%GZz~jzBNh)beAcZ-azkQ80;XsxLgsP!_LY%6M3=7oN`PH~RGKi(}Sg zdy628gARi1i#mdZHdmEt!qTAD0FH{9O!;8g)R9$Vqw#6&DK(}>8z&O+vYxz;X;6-s zsu{ksZ5x0c8e?hQCGU)D-H$T%rTmaKVeD-I&K)&2oa&932hM6J?#?o$#F!NEX)_sq z7aTNqc&l4X+P>8!nq0F&7aT8!+KuQC?D4CNhSYP&OpkSionoT)8c9fiK}3C;KCjFe z7wy*=#56%-MJ{IMK{MovX?fg|!oa1M0s6>FMmv86Xl!hgg-GE;Ip!wZGW+VA)wR+`);@y#=+kUj*u~VgcVSJ1Eh(dq#%Q&9LEy%oJ2px#CXRq)@R%M_QKALU~Us z(IsOYHjnckl9juvvc(&GsmtQ_9sNJGod-PC?fb`(k(H6Xl0C9zhKwWYoN$m(S;roS zV~eu4j3^`7iI6=*W*H$e3Ke8Q0V)OTUw5B6==6z6%2j6@0u}d#+ zd5of&Iq^XUUTiXE5BA4N;;bZA7nxx5gE75$M7O>$T>R#pXo!2O?M&K_OY5=Q!M2P7 zpFC(toXWypr6_@c8MvQ5#N=BVW|@*y3>OEuJBzS=W*yI57)YyKkX%|F&|Ro6FC$(JW>-=lNSsn?=_fAOy<69 zX7I5Q*Rhv#SNK9pEa}HKf!Gn=3~WWVldtJKUYv~>=XJ3GKbZG6oI0t?KAyJQ)1_DToIqfLPE&r z&%IxeKRHwY_JX}$!gGCtIg7^I?oUV*4_%%7I)gSNZThIH(vU3zO(89fXgW9}W?`FO z0EaXFc31dXzSFC+a&bxx#?V+HaMWy!OFXvaD?%4(Oxx3vAr%A^Kio4$T5&ai0-@M# zs`oRD@gp=|(k8nI&5t$dPX>Ohb6Y5Lj|x%N{!4(Tk!pk!Rh(#YPH8XQEGQ@N{6e`&2^GT4n~}FtBBpCKj-FJJihpX zn_&ZsPd~aq##-bX^Y92j#5J}HR6OjgC~|6}EY7He8(c@Ja($__MLsSkKU>E_ZQ*TN za{;}|LLyW4P847EaBp>z_mI5LcVofNtc%k9Ao)$eAK+@C5A_c!qcf{fLuye`Sgq&X$m) z)|4JZ38-QUkomK_de&4Iqzvf=KhV1`hp$1R@Kg_LrBa&qp`9t8C(H2W4ISSAnT9j0 zbx(o<3{5bak|vT^K1{7H(l?NZzzB*`jF_8r8Kp!A{PBGz#&)zAtE|o_85+>2R*XJj z64lUddZ{yP^+qjDsF$yarN0$FIX>Sr#;U*x=$K7mnq?PG0J^%X1R8S=Yy@_)cjO35 zN3puHMZK?h(C1`3=_7e7BdFUd4UdHiH+gGK+Gk3awRJWnGhJP17hL<~Lbt?Lff412 zozhB7d+!t0?V#@rRP?oSwafe$TNA%ei0J5s*`wvX*!-b)nH=SFWTuf_k8Er-G`&-Q zGMYbkZ6CQpXX$!co60*IC=u&a9VM5>OO23|r}t4h_TQ5phHdTo+b`L-yV$zl@k@Uv+~ z2H&%7*fQN*&&McPD&;-RG;Y1)X{c(X_-;$qNHx16TK@(G5pHx7T$-Bb`WW+iR>tflUpks$KG+2FJlwa)m* z@<}<_Yt3q5I|f!-Lw>Cmnw9MW%;Gjf*;~9PrCwDgX!lHD&{8vt@HTRq+))ZLQ5ISl zQk0NnTYzdMF2sI$?#p3pMj!1$uS=G=82{B&R^!>dorFNS z9x(l2({nT+E{u}L;@$~hfEhQ_^{I5EvWH74idkl!p2#st`iN=n<fLNl z6DH;d?YVAGY=FX)VYnpstgSAw(?`>%sx?0m#%fobgeh?)2P?5BJG7Vc?+A2&sMYjs z?cnUQh2S>u8DJSyau=iTsdoJ)7+Y~F9^!Mf2J>$nE-LrC5I%Z?{K021XgvUxq=w;`dfm0IFZ4NW+7Gkom0NM#Aw@FG*ES zvh!&|0Xa5nHIjKHkOIHzc!_t-QsU9h*z7|7g(=_5MEV7Hg$kCWHl7 z%|0HxQfq#}lQ5~chc4Si(Tstu;2U-><*HrSI<~t{cwB%81`eeUr6 z{5a`{=p~Pgio2gji-%v8P;=c=IYSvx-q{6Au!%7P*OHrv2S&SKcio*6idEilyQ)jU zw50d$L9?LrN4@pn$=X^hu`iCDo&mPB_0?j9PYZ3OaI?;zN%OF#R{2)E@g>Bxqq2f_Gr$1V)=Ws^Ttmfe>IkI?tn2vBU zxYwp-Rhb~1rh&HSM>~r&=gJybb96%dgx3caD~Vd*SR6Pfp9qv@ zr|r=5Awf<`#?Jl=HpK@|PCO{bCN`(lHg*cz5*bBGYdYQwDy~tgg3Q?l8cgVk#9mo@ zN$SlAss`Xtr1MbMO_1?3+IQ8pgIPo0Cp@f*+4w<=W#PHhP0hNh3pz|rq;2x0UCnxz z;_b3uVYtl?cN| z%S_r8jaS-?OL+sGSrZK9jVHV22zotqy}H#CTlG?1BZQq~K|KsUxxd}8=*JVbDzW&` zFSwB}64TL<^?@wDW7w>yb#QL=*%pOd#F$@1ogcnK03<&@yHUHKF=k%gJ>nt; zq>btxvq1n+0!DevJM`k}h?|NDb+T+0R7vX{R(IbB_>ju{q0^Q8Hsn}N_7U?iNh37cS8o^TRq@<+! z3nQ<(7Dl|hZr#KXYvZ`>=Y1R9u0>M^>=_;r^JXh%oaSmrAhFuFMpHqZ z0f`^n$z;Zya+S+B7XnUBkhJbDu@XEv%LRzLv}So$2sE_&hFzjND+DlLvFgk0v@u&Q z!I<=Xbe7YYMR9F`@ax;__Ruvw$8d%}KwZ)g_bot80Zo8%uUNAGu z8?8dE#JmzRkrn|T!o5@M+(^Ut^XM01EPoxF+&`ibnjN4xMrxEXwY6pVQsB)eg(WmAgW?OHTnbCDpo;yMj-;8X9)GdUUg=67p@VZ z4XD3<9{oljgpUlONQ~q*UI$er=+>ug)Ej@+IvXJ1zF4Ask&%~ z_w4#Z3Ay-)9GThJ?R%dGpJnz=$+wP-C zPY#Y+S+D&D8Ce}GA9GENFw58un>|l^FI>IABDnOThl+-16Xp(Wh*Eb^W)8a}gE3)y zPs!(;HM-}QxuVBQhlxqEF!&XqJi{!5j7oT3C);9P-*wEt>92TKZ@MYZVYdk@R2L&p zK08#~@aC(pWW;J|RZ%kPn4wTAK@$r0U?N{PP_$S{93x1VUCPMq90T_Cl{86zYIPhK}^i*a4_jf5v9=IX{sTYN5` zDc!ki_`GKmn|cFqoVr5!E~KfPRlYT&Ca1+NdeXcha2yw^woI2$nbQS)K2o@>=xX8KIBdq-1vb zM(tHetJN9?}8;x}G)%c?vcP^ZtKlMXDHF{fCY|N0fOyfp5Ji4R^7C@AG5(9If>gaq94 z)iw5{DrrfbXT&F`kn6_qS|6Rik74zQDKmt7K5~2L)PN})mog=w(yXv%@(Fx1L>APx0UtTSy-`x$v_Gy|9Q8QOQ z6*oQ+E=7V~qx$gm_tUduSJy^#E@0rF0ntVq&=M_WmozgxW@2b%9bBMdoy_AborV@F z8b!yyVD@+uiYII)L%{^f>8=zHtx$ea6butLVQs(bOBgrUkYH>YR?4nMR59P06 zt)i#UY0RzU%2&q<5aVQfMiY~yFxcbl1bk`*OcbCe418F7<9+Q8p;--CD;-s*qhyI{ zC%GDw@o|cZS<2SkDeIdUuu}tO7ERm@z!hqYpoNi=`i{7Th5+9mBvTVCqL2C?>~!C~ zAn66WF}TEJ%0<~8zm+N&1O1xR(ZpanLfRdUuIniSGpLAQXn8`)#g!GsfAx#ke6w%8 z{#Vz|iFA$d{7adlo~&#_#h3ATdL)^+lRz9#IA6s*3{4m^H*tucYz8L-qAj~GnXN4w z*SN-M`$NpD?X4fmp4J_Ct1?(z6F8C=o75^Sa>Y=m3YLhUXj}5MBwL9@DL5e~ZMw1_ zEt{_XP40=siB_(P&B|iAGs~U4c|xjlOof&=wHdHxih`yx7T?)iEMl8T(^ZdoO2GRn z^zlv60HD*$&6nwE94m5Wxu->D(gNS%WCcKim{ViszS&e<#TOsf8G4r~SSbDtd|BVL z<@Ak99dwM--9f!f;N3^+(j$}X_xr!jaEan@x!^DdrJH-Cy90*`3uT$r(rQlNmM1OJ zEJvNF2iHDyUhQ{rVcdMoD09C+d}5H78f&gR2tNNZ3BK*sdY-1ewGCAv>Fihe5YwP; zIx}AbqQ-Y8dmNhTrdBNH`Ry7nCj%4q{iz}8M}<$wZsgvhVAo3m%*XILj6Sn!s>k?* zJ|Go1B2wD`R9y~kscQDH_HZ=OK6#HcCmnZ6-4P7Etm!@0nBY)XR%Be3oxy^u+3Ci3 z%~*@SlFIej&QnT)>L%|cW8v>OQlgvzP8DpiQR4x#4DQ;?lP!J}W3UIF%8pAZQ1>7K z@-INwVZLcAsh;Py(RMhrk8j|$Q?`%C%f02wSY)bh8?Nu&MW51s-#1^;L9sSUz$NM* z#iqQ-YV<5bcW6|>MaOX?a=X|KP*`VjkIGubmaR|aN?CFs6F*^B20pNge#tAUDrh6Z z-`=t|A6q27GG*80=>jJsUoO?o4iQRUlRVqNy-#ly(0-M+`v)Nm>SzyzI67HEV5;Z1 zUaG08@vf*9bpg+*cJ%?ffGR*`WuD1t6~1;p9<uFfTVaYRQ`S4GDlJAnsx5ACOWX#4)){`D0x+Tz}pDTK4X%=VpuBO7Ra4F3fH zJmn(WCz0vHzTXTe3sP1DfVFsmibsKokiZz|zm3vS#;1^s`Su&bEMd+^+F~Nv>ZAY4 z8;`QUN3!rjM_RHv%8&%fFdO}VwXUPg$&t+89Av(?RCbgEGm^wfj6)<$_LoCAQjiu& zQ28)H2>c7DBZU}{gnSPZ`m0&vQCb{GT6M>2AsRm(rOJz>ih1Jiwv#+cTL4L0{cmeq z+8-$|f+YX&pUD60gn1N$9*MDf7~}t|aU3PZge1j_`6q=v{`}suJ52AdHRhwV@Q}1} zG55dC{PX$kHRf+`PmeNYL^9rMk9AxKIZBNWNlgmtZwDmQNKpRLjx-f6W5T$9lG=*| zq5H)Z0O|mc0sthh3;?4_l$K5g+QP@^`nf%?_DfvD-zTA_EDr#I0jSmivlMDx@ZZiu z8t6Uib(($FpvzitdsO3@qTB6e@Hyfv+*ckX<8<2JhUVu5<3XAq_r+#ZX=WlU!5eTX zKcs88CkJ{2`J*SCZhm|6kMrRkEvYBXutnGXExdR`EDV!Gk3?dbZeMV+P!9YB(!vK$6p8Cod}MN^05LOiws8XN zeFKKN!?iNF;N9f$ji@beD* z_41B>Ts|end>@0;OtDd4ob0>5n_D5h#)EObkQ;S-i`u)`zjgudyIf=c74DF^n@Ec8 zc`W=Mw1wY;I!L@H6aTv=>Y5NEQ$!&lR3CB@J9Ee3%rv+k=14x2O#RP&`1!EdIsMvE zVDD&q*j<)g@8hC*8Vzk-=vO~^gi}=0|7)iX_5ih`J;H;L^?#?oJ*o$&&4Bkk*l6hg zyfrW?2DKL~0uzRD4Cd(0u&5x^{+$TWMXbLKIv9c4`VxV#!2a6^q(+#(JvAu3-w>o; z{68TbHKU_;twLzSi2hvr$XOhUHLAPB)!#}JO|If05oZ9#xQ z4bc2U)FDYcN+EazsEYm%L5G%wM`fW_2}iI_GX7K6!6ei=%Lo!b^PiB8tGbNJLoLCJ z;03V$H@t&ssFh0*v|5foq5XLsQ&ci)5kLg_6VD;!zgH3v6^L414*|sB`|p6q72Er5 z#Tun*8^V+G0{@aHhrFFbEdYk_#7XF1@QI@ zo*e84YP}GI9}^e;mwp^fM?JERppVG?SM);?29yJa2;2kZ<8Xg++z^$AddLpJ!&N9?1 zt^N9bwPSZt{r09DW$O+?IMopSA8zFN?R^5uXR8Q?iTOWb>|f2r!rqet!T)mXeY{}- zA0)K@15ir?1QY-O2nYbdTV+(hAI|U9o&W&;tN;Kn0001CaA9L;Wi4%Cc4clYGcGtT zH7{&wVlQoBc4clYb7gdNX>Mn8Ei*1SE;TM{VRDSRb9g7wmM$FIwrv|7+ji37FSc#l zw(X>2t7F?v$JXtcJNM3<`M!J3)bmvRQT47}RjcZK*V=0@MHx^q7$6`hAfSF7Q&ph< zvO)jd<-}Bl=%wVv85RG+(Eh@p{vAf9`@K;9_p%r;5D?mbg~2VkA`%Ku{u9N!Jljcoq51FxFciXY#z}wu%CK`ZZ3vAWLiP@u z9`UBeq+4aL34oxZ#>p%cWkI^v)$6|l37^gF#D3InNKDXe%C{&Oz^MXQw%ju_&h#az ztBFwS%5feA*y-6lqQ1+1wr4+CG><)qMZZwtHy9oWAzLJDm;Fe^d)a=VYz|VP8thou zc$wt=hHlygR{VcD0POE>=V;FO|3<+62g1nS$k@X4p8%2n5olxNYHIsW;5h$(a3@n| zXMnA_(?7Ap|EG2UyMJOz@~=$Y?d@6ri9OK&vQ87g^c~LQW5h*d1ns_0FK_sR!i7-_bQ zReDZUcxV7oG4ONsqqc$#3i%(Nm&f9($aV*yoy%wb*EMOOuM-sMek&#plm+Yp;kZ^| z9TahUiQQ0=mtA>HM-*%k2@F~;h!t{V2`}?$i~h0z*p`NejEBL|c`OR^qp?pB&0Dss zbyC(f9vET*WhD5j0kze1fdQGQG=bXPQllsBiaVM^UlbF$%?C&+c~cOg-aEziS|^O{ z^!0~u=lAO`kND?t6g7@qT1?I9%&&;kBxp}kPRE=lkjrvWT&2NoPSYS6KiF%mpKn;3 zxtSR>c<#}B0nGb z)4BtSP2Aqp%G_b*;Agg@k5 zi<%*CA1_vR_&O{&;Xbo8>Ym;|b>}&pjN9sPwkNth17NS~u6?zmhR>zDy0!G^uhTfI zTHM{7C)3iyxg1~_vn4~W>qvMA3wM5!Vq8Jprh%6emYkosXs2O8b=sl>Z1wh05~y z)FOThRjZ8)_kg@EM{nf3$fx57Sh!Co8&`GiX)+ospwY_t)qDQJ4PJAbfKi0TINu{W zW?4S*r8fg!|E?(AFGZ8O&BZ=7$gIqM?(&R@MS8g+CZ>~J@yJDZDZ z7dE(4ZqjH4de*u@p()_~awCQym4=odJ?TRGil8$Tqvh>T zJLTJ4i8-34RS*A^pS$gUZ>}R->o9%7DS|H6wU`awJaFxlkZP&z&+Kj_kL-DQdc0-? z@PZy24MGYX>_XJ@ya8>Rq`;yG9g4dc1}g{AQqHsTCr$cs9LVbSX@8{U=pE~aea})L zcH$_dqI-C|1D_)|FCm}p)XOoh=baXxpjPREHcrSjl00 z2kSJK&fBv|X`$m)|7ye@M~e?GWDT-#u5xg@DPn!BAH8vGCgv&uxd_`N71DYDD8%2^ z5W<~n09OZwVA({S8%|SaOjt;VaUTRBpTKluaJn8TAAcYlb3ZAnN2C6pluX6=DQz4^ zW8xgLem@As0*RA17HIRJ3;yG*o2*qx(VG;Xr>;n~+8#05H=JOEW;1d#q@#Z4%rPwh zn9Ir^2Pgxu6hxu%6D-^1&!Kk_yKLBhDA)?jHgcEj z(VsQT1XOfU({+LapQ65W_Vj(g-JR)@{?vYknLftKJJe*oBzwI7G7uK#X-JGURqPYS zii@bg$h3}uA;zJ&#<-$IS$~NM@%yj+HD$C0+8xj@86IGga|le%AJjtH>Ww7mj*y(? z%ST8E>~5->!qSxqU(l|C>H=o8306nqj4W6gqC#di&A9fPj?St_fYH>O`Gv8#VD}2P zic!PhGc6Im0VUnK$+>8R#I}?tRN*|iODaW%qlZ?~%P>Vz!UUrkagx9#Yw)L3l9{E~ zOSX`>7Z*O)vA!AQ+)e-RxU0F+pO6#QXhW!q;$o5r(kJi5WX|Vp$opmeHZq`3$Br?< zoHBwCg>@(Ub&^%~8*R5Q0a_7{W5Y|M=WAvZGEI0X=&Di)*pfuS{?kMI;g~?&!73nw z7fV2?(0h=xE2>^Gx<#y8GIw1;s0X8IeV&&XxRg%uzwO<%bini2kbXg`ki_SyI_-S# zg%)fCqQ@KakK97flXG2Of5Zi7$ViWwyoN$zcKa=b< zfZ;kz$O^e74Yu_Sdac{XvV@p!IO_-(KoSrbi(4o&cdx~I4Xg)g#QT~begqy;9>?Jl z!-p8@Zwci4>IbY8jlar_49TbTR2^?fkqsx;Cjj$nqQ|a&iw&PEr#gD|NR1Y^qJR6t z+Lf!G1bVy%*P$us(nVfdZcR()N8aol6~3iG?hEE0ly$=eY6E28FaHElb%n`T%wSN5 zu!}1C@)#%(%o^DFdWC8%n4XL% z-V}w<<7O9HMCi3xB`AAENL$waB6CfG4ln?zH3!I;5*~3;z&B?DiNb~%!=3_>R)RJ$ zizG~qI`xyI4bEvqdk^HLC+hiSNY`OfED}Ix5p(Il7j(07FC0pn`!QyV_$vobRoRE@ z4_Qwc3(nJ~iPzmOg%aShsNV0SAa)oj@JYxGi*l2{)7mSz9c!KnRp*%=TcjcTY}&N7 zNez@t6WQHqc|gSt2nU~#VS~#y9i*@iPG+g$W=@ZYP94TWB_RPCW{$WdOAt4XX!_I% zuHq#v9k<9lUT8us6pCIIn~x$hiFF#G!v0oDUgmMpVu?IZ{h`G$W|)gxTu zwF8lt@%k%&yrcR1;aZANUxqAq1KlevD!R4;v_LZYV>fvzRd!UT?E&*E>3#?n9CG|tmDl8LMyWNJAt(+X)Wu|>QIiXk0x8uFbC(wZ$a|^y zBM*N3AJBS~+5L$fa_BdzJq^PZDWn4v+wwBM&Sl!X44;XhXFcgT!%pfBK zXihWIAy;p?zE+tOwsf-DmCk9xTj%R@q5I}`X`R4fZcoP4MiR2cmwAjj%(1+2u5vn9 zeloA=B~;8RA}+>%|#wAbfim@A+}AIdPoH%ZB$C3$5!K-kBgQt$5I$)tXAN; zfS`tX%lwY*h2GU?Z}`E9Nyt-P7@J*6U{s`R{4Rsi1e?gU!-dy0W}TiA(~yg&M_wAo zOMvK@er|JjcJH^4>5(aBX$Cw#2nFp*h^ z7?I*)j-|>S@hiKy`h4CS=u~G%YBb-4{YN%SP<4oHr2*h>+Mf#nN$W|k)?=l+oCfgI z$v~}(c_;hQyp}mP^Q{C)S!AC>j% zL;LGEN3+@&!_T0$*8h)153ujhS-A}5TrjN~2ZbEAsFO0b{W*{vLq;SHi5E}zoizMM|xX&r|<|H@4%ZFm*C0I*IrJg0GcBTx*BUAJtWhBC~g zX?lRq=GhYQYeIN0&DNtj2g~!~wghL6MW%1=Ndm$zfxTS#95jrIw-O zanNninla^2jR_mp8Y^n{w1i!=vz#j~3U^yCMgei{H%FxEag@qnW#ciAsyU@ zES49A9;<-yfKyMB&ACOE^wMnY4UFN)QpQ|IGd-~q(aKyTb&iD9f=xyq9w>!~M(l4I zM5U;Oj@#qiadDnmVETA#obeBVsF7$6aXl{oIt>j?jhSu;iC#uqyS;=X!JT|qfHqLL z=S>~sVcnlSyW$CfZSww|PfP}?4=c0c2%h(2n-k*Z_pQn z9W}b>@nxEUIr57I%U;zMF&Jt=<@H;mye9)gt?YByOV5wgBB7US25^^)#ZsPpOeE+Z zw?za!ykirtuAEUF`w0FgaknJNnV#xE_8=G>2#n<~06|K4D)|}5%^%6c#z(DD7G{Kz z4(-}oD%6KX$FdNP<;5;2i->l-Bx%r#l&IFM+kP+ z+*tFb`;3q;?`j{yoQZFVjay&r~E2q)=eGJs&T8 zv+i539Lf32;;O}5Brcz3A`2|s*lQs_QbnMiXSyBV2-@E*eLhiCOUVreX7lz5zH(U6 zl42I+ckBmbf<6MuuwK3;dqHn0nrc!q%aH=JE#QaX@M<<uVbU~R&Bu| zVFj2BB4MSvd&NZ5EZOM`@NLS2W1@_cyS6*{wBRM>vmbjmj%e$m?zQlIj}Ith)FN+t zB=3?r0c)!K(Zmhg19!UJfLd($w#d)ns70HF{_xu)j#!LZc9K8pk#&fAD+k(z|HlV? z(pQB^2Ll2Mg9QSj`KQ$;A!BENtC2In&X&R0+Q`W%Mg6x1t{U2Rcf3g=6Pq_ifp0N7 zKvH{NyQW1fIj(RSt-gRtvue=9Kfr{-jH20n^OxIo4=m=R<^cCob}Q{ngO%O|;of}F zHZQhtI^0QgRM-2q&-1g_wQu+My`Qfy$S#U2D%OBEo)O)RwbH<7S9{72U>Uw&Iejbw zduwIT)rM*V<|uz8U-$wTrdW?{K@4_f^l6x@8&px_l@5iH>Zey@z~Hk`oS}74TEP<| zEiZW2AO2Lg)-Fo7`fH+}uF}lw+xg0@DLIl4ua2Q#R@z$YqC#b){@}4w=X8`7Q{rsV z)mod2&MsNw(9-OnrckxsV#9zjA*@pU9jV^p20j8>fT8C#5W4c1ND&VmoJFcLAWG>h z(ndKR_OQyLG?gw^D0%E6l2w#nZuwbNYjat}sQ&Ccrofa)B-qpY`pS*A7x=MSv<&0)EveQSUf@`HvIo||U5;v3o1nf|^?*Ktq zxDPjb)_35wm`(T{_Ry7rs3vJe9)zAl#fzAznY@F)ll`cMe*#<0fDw43b>K{Gy37P0 zY|p!%#QA66Sox8-5z!U_7)Q8f43i0{24@jZ%`%rRT&PWG0CudIsgaG0icO?Kp%!v# zFiH)qSxu!S{7F)n?m=`4b7T{X{*VmI^npk~0?|r*!T1+6Ri`BF!fF@-K04pk5bUvKl|%%d)4`t*|Dl^$_} z9>HgdQ40@7IKohaTp>_WG^TG%pf zRSDQ4?NDiV#ce|S7Sy#VD!c7&g6JP^5ihbkvD z*Zcg=g@YZJT)+L*hU_7wHcRrU4tu0E^vb?rveJh*w9=TtQLPq5E)^r|nPG%ttHG{{ z9e^?M&9+?bT;AYGJ~%_kbTC?ySoP++wC{v2H;)Cn+P5tW)Vm8OxS4;U;;v~ z>3KTv`A)(8E?|9eHGKMz8DDq}ZrEjC{K*+#ybNx5(I#B&PazRs0vOX-mw^-#+0$g% zoF>XneMzQB!}d%DCro#-(>m<$*tbSfN@(sJ`H5@GM(rJBm{#D-KHDL>b$d}(?v2~q zuhK7gjz8K-^lNv*FP{INaLKsv@!lOJ_vrW{suhge+ke8`Qu#Mn|?Isms@e)mRk z3-UFZ_ZIE#GWNR{{6~F@DD8zO0R;j|fB*tw_#f( z^}e}M@_eD%Ev{I;e`HCynz{E4aWSt=vmDDf#@zSb_bfI&D@&2UdlBAs=~8RK^r^_T znZgXe+e~-X$II&xtv@%PI&ghfa6k82hL9=tHmsVw>C~ z8Z6x2)Ra@GWPh!FXh9+1R=KHRc&qG9Jx2z8WAo!he%S2MOL-R_LUltv*S(tocfTSfh`Prs)i0VX2A;oHR0)MxOO$P4&kI_RPIL4Sq>$`?dYVqky4&n+b~ zY75zUejQzpduTgdan8%+DPsNSULYsN6srLzxrOaBuO9(So5h=c z84~)eJ47-Q;*CN_YG?T;af#6;shpDaN(8?=7!@AQx&=pdAP)138e9@T{lt`R4RME! zz*tNGMbn;jbzoWc^ISg>lL;&aol%)a&OSD2qUTc!nNF1on%Ae9OX4=fjirX?yq z)v0>3h;fuPAYL+aK|4&!PNL)E)wJR&Czq^x#iZxZ9S8DiqIjapdPYy%j1A$W)w`s*wmF2E|H&6sXph-8<%_UH=T&!&F@oD+YjVF{ z$M(WpkO$z8m3zDxXHT-3P-fVCvI|QTPAZ!!oA+?Mqq_(bTyowGz3p;Glaac}jw^>P zQ*rMJ{I4%kaEG0BliAi_!qr+41Kagj{Am_v%n^+z&bGSS;anhoY{7sKOob-LDG{`*R3Jj)=NavVLNL0rr%&70k3rIPjjd9<2oD|U zjh%}AW>H+O7*>c8`o4yG6>P+B5#`9rH(sJmF)W76p^o~wcOfI8Dfz!cUCgcV$oS94sJyanfwtvo2D z!$4m-+h_?l`EM)%v(u<3$$6Tzt4uYaB&{|-OGGn?4RS5v4PK0Uh7Kc_ve(#LRyLp# z9z=^qr+0aI?z3G_V}`e=_7mu`5vCM2a!B2TaM2X#t=1?AsjqPIZMgFJarw+6xt&iT z*ZMfXOq7!|DqI2VAeK<1dSZ-i4nswOwu1NtbqfJ-Qj+Ks-Ic61b`AfqO}(G0X0Ek1 zH)I43(>gF$T%3jJ9UaLHAq~EsJ=h=5s6Tf@QFpWt)!o9LHn`diA+oS*7!LuYCfZD` z4$g%k#&&b>;t6I2sA6r>+_KdEVPl2~UFenf$P|Dn6KIdfam7klRgfY^aNXjtieD{y z%kIBU!QsX36p&c9cY05~kT0%(4SkiO^nW_k=RoDkgCP#}3z4kKf}QN|=ArhdF`)*S zQ)?5*baLGizC9tRX>1!n-B}Xf)f?=?=`P~ zBy_(ly*bWbLPz}#pDh1FLMuAj*_%2#d;FgeYW43SR0oEdc&v%&g(gzjqJXML2#ls& zlfXCu`=hm(7EA^u39bKc0PXwt0P6iD!M(kOK~>_rD{}3sFwO6Fy_WUy`hJh;&rEl5 z+Q*MQ!nV0`^J7p1KF*mfd3Ka1cei3QR)UFm#hmAynR?I(UL~e{uo;e(C!{$P6UU5w ziaFS(haPL4RmVH5>~3>g(iC*2k#hw5+|9k`2O=&7-3AN=_W6ELRdS-MV{oepoemvF z>qtdw(vS?J<7Voy0*9rW|}$?5|NIlwWXjkt1eqa(mJY4w+5BoPrGY8u&?grn4NP z_2rwV#hL6M;Yda;CK1PkPDQu(s%OeWg2Z_#I@&uZW_ z*J<(M&;Wu5oN%LbVh>~kEFMd)ekS|Ko~F;h3m$zUN15cJdD`@?C7)@uYHxXW2>rd5 zP!CYha9sBwI1vT96DUD5UZLu0Y?WthLbiG$Eq+NX%^?(#>x#>bKzz-O{o>L924~!M zIuSS@xSA!7#15FoY*qEy&7&H|l7=b^4tm(M*)JOBIq1ewdJSh9MxLA#f!{Wx8NXDB z^z>xVMX#aU^o&lhLalxea+h1@;8pff3&F+QvCG^CDp1O)PgGlbPMfdwW0$C)`8=q* z5e3VOQim4XJZwQpomedO9WE+%3I9T?iC%sy0Ij!+bWQmg1oF#1rcjAwm&bN?qWJmf zunr0}Pe3Xek4IRKq9Ko4^mCmUXBi2;sE0WIG~3`KC()3T;kQHYx`Sy&@NO+Ehm&}V#Ld|lgS zNt*%S^A?xd<+RL0FNpkbX{{pGtig$1Gq(u!IS@QHq%_?7j`)vEGxIq*{kKHb=P%Qk z{wdR>OiXQ^0cHTBpVp?rMo#~cs^+L}C@(0Y>4oVl3nN)~c+o~GYm*s*iy?);z@RBc zP2IR#AR^I8QAiyga3h3r#i%h z*Dpyb+)l{|0Dnf0romFV`5^{2NJH>bcbHUm?7{>r?nt0SxF5BHPmQT2@jW^)I?x=( z3>zmJM1<|v;B&kF;c;s2J>KAErXiF9PU)T;GZ+e}69Y4tVMmIFu=vbbL!&CoFXQlop~8G&B|l_?^}s9fIWL<6SL132?}n zC9(;>*d7~Ha-M`Non`Pv;mOiWdt{6TH(Nubid>(&lz2haE@X?5XDWaEWu4RSo5U%P z`cyNQjfU;<2YKe4{L>OYVK{gT5#CeM!~@aqY^EH*w8d4y2G?HnQ|TeGCd>K_cz}Yl zO&_|p+PV;$(D`pQ9ss(E?x4$h#-(P;G3lD*2HPB%A5pR#zDZnuH6d}MZ}^A_wk5Wl zsl}X`_C&jLc&aLPjiCMOFNJl<{sE{LBVI|)`~^YV;8`|sykVjdZ)k_c2*q;!#J*EG z5Kf0lb4d-;M>R)XMfwN`Z^6L_3RXFfLPEU}cpPyiGhI(M^gCSK{BHTkwjiL%cK7FS|k4JO`lq7Um|RxwmQtkH6o!-u`g;n!9Bc zZ@{y>#XCKH-}~+Oaewo3m zS)|ftCKyJ$Q$ov!cF^vRUNtWY7si~##x@7V5{Q#Pb6hdS#D zgoR;t<_`5iT#D2B2ipnkfkv zmrvuO>j-b4(40`wLEov)jpZ%DpcG5t{8^Ui>`rSpnZc5Jivf{Zcl4CPt(=kr9GCN` zEe6Yw)?tjQs$e#j!L2p%U~?Y9IZ;%lE`3y|=BUhAl~k9kaSS##2E}@XVoqbmpfKws z^1B%mOyC}QK+CO*LFc%f5p<=mOtji2TQpe?so$GJE;XVeAc_f3Mw^{%n1=Usxk4q`_U{oFVuy)MsV{HbV+(HmN>))McwOX zY5DK+*H^6hRSXe`4P$q-87avRogK+js8clP4a@Zd@+xHp+|nBK(8{0XKM-mu z4&0#{4q_u#%$I|?So)*5d?BL!v(=*G^{50k1Au!I1vqY_rKmyXu820W>N;k^s`@u4 z?IjyH9kD{GhKKMHOuHs7TY1VgJI?^sYePiZOs!0Fm_0c294|6b@jMEjQ}Z$tOHf~F z)j!P86~C^*32IR*Y)vHCQ6R~JP)B%P~5W_3r zS=R$VIPR3UqbaQWgTn1k`fukfP|Qy*`L}cLo|@a5B05HiBSuc%kV^0#QJ!lTNs3jw z&Ui9aZf9MBRerA^zYg_Z*((y)Ug^5su&)i*fx4$>rbitoJwmxjWjBw05ZGi58H<~} zVkGOnY5##JMCF|2X$aS}1g^rU_XM`Nb!C9nYzlYx1jcWxf1(X*4vE#Cy==c0PQRc+ zB`kUZGpLm+b()7J7QzjwB`}A|wol!I<~w7$d>HVI?1d^OWdTjA$Mxz$5{1{mJc!CJz{oHj5*ewI?HxhhtByu+(YM(^x!GYQ)g!=Oov;z<3R0!Ia z5a+Xt2+|K}KMQ(Y(qa)VX*t-q9Lcke81Xu0bm~~c2XRY|qroK*JV@I+7Z-Pf{ofCF_5^WI^bba4Tp3y8arWYS2>yTEny+3=@5bKu9F zTDm%Ui`CuX+&#Z-cU(f~{Oy6N4$eGoWp9f7d^msWg13L`?9I;^`vjrUsUeAnsL?r- z(y4dmt8tEkf{fS|XTg(e|GjZ)-GwR|)XDiHvH?WUzQ^y-^Z~W(%Us{M*FMwF^tbPz z(#N#d9%A-Lo=XN=m#j8(fDjxrr~@Wd{MP_9_Tbg~a8XZT2WI`aAhr!{)&?-)r{Jz} z^BbdK^bKaAS#s||?C0u#E6s^baG)Ii&2}n~fq*Fgd2g+wo!S4b$(3km*`ukU@#oYe zWlaA}1>VOHbx4%L8iJP-6+sgVLrMbL56zKEa!!|x05{Ft})rWcQ5tTYtnBEaayoU)en&2QSHy zK>@aXU zR#MObW9d8vp(?2auz$1SMP*rfBQlpsCYx@aFnv)4?ZtAOS&9A16c%=9TK)w+vB0xD zh}?5svGg}lI`+cRcfCI}oe%A{HHnHi)>~8s)uULYY3tzxE1oI`BAMLf2*Xqraac<1 ztxD`Jx4G!4T17m}sb~=aGFz3SY@K$BVPWr^$g)xv@Y8m{BwTrCOmwZV2)xj~dz>O% zzZu}oprR{o6K?!Xm3vtYNV-yN7fOdZ?%!D9<&dbznCkS@P1T!i6dUyIinpP5-0{vHk&3=&kkQv`SMkPQR;qjJAgw z*S@Ny;;}wOr68ds?vq*D>}?KS{uRU+fKmcZk8UA_Y1h;k(y1OPS zY->Trq4zDRnjJ=ohH;j4M)0!t2l*uX?2xV0+VFG#K?iJ+)4$8ojJ9pir?)4*H)4`1| zIJuDkxxnN`tPqb$mF~D#2)*@?S{E%gxNb~}w{$ziidl?Zv1`Pvg-j8dGhPY#DqGNA z)5-EcoQ_TQ4{^>YQt_PA#w~*|HLW2Rsw2c3)CRi6TyYPAU7|c(>%P=zON80D3x^>5 zYQinN6#K4D!+P{4FfT^>wkc#fFA)f(b%m!%F1O6haY`j@0B>NWN;!0dIZjVe`Tm$6 z%n4M4Ap8+oWt^jpgrXCSUIA+PmN%S>gc2#)s6%Y9%hjk7W5cI@pHNV6lEo#wLnCQS zsqC27%$N9;|D*sB+3+PO!~1Oi7&P6cH%OGlwk*%I+(8%HbX~818yf>(XsRMkl)`?Y zoec-#J`zT}Rlf=&jys_-#K?;|X{^~7wpKLRy+vS`T;elz;|r2GVQ9cr@}FHh%I%Y# zXwcP=y80}OnO&ybLB>^MCm-;n3;o4i3Km`I-)BnX8;>}5j7q%WSq@S7zt1jntB=rw zKM*rbH`iYfr&Am@b~F=lv(bMIQ#(Z2cf~e%Ipw}P&nDg5p-*|_PA{U2e8S02(IaJl z_tiLE2l`JksTrG}P{w-*EE(s4x&|17gH_F>9$#f2_UFORpN;0-s>lh-u)H2Tzj4b7 zN}Qf(G7BcYWK-40;;isoT0iXjNqk&K_*wd1tTI`}wYUFR`y6U~_lRxW;Ibmd6y}o~ zGC29M8O+-lUey?mZbQ6Wjd|gA+)s#59f_wNvgHZBY_^$k)G`x+&Xrum9P~)p@RbQp zyHI*PF-J=_=@j#B8~ev711)^@I_3qgJ3D7Mii=EiNC!qj_aH*EQnW*r9addJe+Yj% z{GxL>%}Rf+#37>X6z48#nnV3N?pD#&=X(iDN#8UX?tb3-v*!E1Rn=8K``~lHfPjKv zfq=;WRiJeD_&+lhIaORWv@Z%WY^b1*Ae$Dj0FGecMeT2GrM_0h!8rK*-Rtn*mr?XFcPi%wwE4JQ^Z6}B!_I$P(<1lK;;iA>m*aSX>j9y^=Yzn-_;cCrZn z_*vTf*oh&|13bRyK~Qxi`^4Lm!U~j>nh!U1Vc$zFa)oH?h4@acvC0cKEBNX z%e-O0)f>iHxVMI}2Ft>QX1So@P{pF*Kp%SSGQWfZpQsEJ-)P{YwL?dDHsO54=T}+$ z{U|%_1n2Zg;=|Z6!2D>_U)y=H-JBg5SZ>2j06jH(5qdOl6$QwEjcxI=$}D97?=VRZ z<*dyoX77^KS5Xfj({2i-K9=6F8qiu?i3|+V_ULY}=7pH?VLG?LDxS-0$$pHsy?BLB zSX*`r&Tt4hQTk~sK2rGc^R>_v#gvHs1894$%XCK>3HcXHr&X$#2PdQTOug(KVBEvg z*Gj$3l%*LQX3=F&Zqn3MDLtO1C1G%L4ulQ0S&;|r8a@Z3r7ACEG;L}`vZX^Ig@NgJCD2t3Zjbnrj-rQb& zkkmc-eeT{GzHF{+j~UJaYq&YE$L|atJcoEIf7cpak7X{n`Z_1)Dn+HJ6rJkA5MK zU6iyYd{EakF~_HMqO~}4DbeTdhS*~oF&u3Ysxwm5$or9#rb-gEd~GxW#4PvZB))oS zDUnS-e93gFKpu@UWa2{tej1UDyA==(VK(<#pu<*ch*S(O&ho8Gyn%1e0ACf{oYcMy zK$`J3b7pCR&X#LgPJbJ@ghqNv?Myj#mrQ<6C)g{d_6F)X125@o^*V0R(-H6CM8xqj zc%Vj_L##<_03F9`0a9^(j$d>hAKojxbmLuMTjWwk3XftVpxh4fG*>W8T~{mfn_8B1!g!W(5ms26)Y#<|pul?}mt6$JTo%xlKav7Ioue@b$(J+XR?ZPDKV`Lh@ru|Ft>i+i z9>H3C$!m6E=gyy7^hb{BJ%uzQ}5NW9N9TPF&b^t2oOa zIRRU|;!$;+B{qS6r7rL-abZDQtNJ^NiG25dV=H49z45m&{7S-&4^z_L9ezOnsBe8J zg7d#YfqvZ=kD6TsQd@jpZ^M_tEhLlleuf-Ci^+=W3-TA2Yt_(BH9A&kSu z!gzjupMqE(Rk;?|gHkEJML2OInDYw}(G(&Zn+MeAT;v=0I|R5VWob2G3wto=>FzAM z={@JO`Dvlo?;XF7cUMbxztIwdO?TW7N~1}0NW#)tZqNl@28Tw=1ntzA&fEc%bLk<8 z&9>sp6$9X1nOPaiD{Vn8v#ADeg(I*~KOO%ROyADv9okX(;0pi8(MbUd-q(ODlrgZ+ z(bdOTuYJA^d%v~*WbNev29JeE^>B4Cz>ve)rhTtsU1k3XU=iTijKw-q(8W!(WCVs~EL=`4%vAts7*vMLx+tHbt&MeZR~of)Pcw3jZ*l4J2f*V-sw^`H0YW1L%0}%AP`fW)Pd29NH z6voz}o#XW^-@^Bprk_#Oapv?{h98)^bVanOV$`XuA)NDM5YTAPmqWk(w7v*?f?O~a z61ytF&xsM!Fj4d}6V>=C>6eK$V)H$8Hc}MRu>Pa6B$r(t!6ZqZ5EX*OR#<%#8m^(V z;a6DPegRW9ZQn5a-kFA+gN3{hU>)`|uaA|+hXvb(Rn1-Hm3t*-ZT0>T)O0HXokyul zTH}ZeC4E54615WJOk2L3rC0#8bRuIt&B9D^rks!gKj0H@K);j&9b)trro|K2pAR}{ zL=_JCRe=l|(Hfci7E5Glo>5Yu|E%#`2kQ%63a6w{k|w%%0Iu2A1VdbV zR)>q-H!~B%Q38v;jp+&Nz%LlqV2F=xLel1f?~0&Zv=&p&IfkPpn41puoWj%z z)~X%fmRBL0joA!ZNCN}LJ;+SjfmZqmgkJ^g4VD!L#`v3x(jq^TBu0kn*u zso9K#z7vL|W)i=KRQ3aH@_h8FPBVA zApc|#$?weIA4S1>$yks2Z_@J(^{*Ot{!khzX!|SFoY(8VlNL+7 z>*qQ~!@^p{H)xdFwSbw9ok1gb;&EOVLE>a$w^8)-{8fTl>a8_35 zc;-gd#?}^${(Q@o4YY*NJo0v@Eyq|@{mjZhMKf@PE4eN@;hk$!_$029JwR6}(Ypbz$Z@zj6_;DSUel&{w=HjOIm1dwkxUT6t5N2FomDiJab%|KPCFj}AKqr6jS`OeVhB=q4EH-ab#nXIkU_6Ci z`3B-;s?v%5teDD=I{UGqmX3iteRGa2hDb0fHAJPQuJ6X**w~W|by&>EPUX1Up1XHu zdX7F}+~Gsj;XLE>@O6nR*v~Eo4VTy)P6Lcl0Ct4UlUdPjVp~p{<27LXQ+>q@9CGqx`a9O!<(%{I%55h)iXp3t#f-M zp!${A#3HGOq}E{L{$?WSkpF5C_CG~O(asuR{C}Gr{^ld9NMErBnyrmS2T3U+}4(C}!b~c_<1^Y!Z3Z~(50tD`huv|??8_-=K z2%Miz7yh*U+R@7C{eC@A0D@gzW{#lcE_O(9TVc~(xhV-1gEu&vwGWxAbJ^@e=}m2V z3B78Jg;RHbRUec?=pCN4$w|FtQ)SzntEb7QmiV)%Cii0#lPObQF7&)sr>%w(fFV3Rq|jzbQXlW(;WEl*>lLpjbe_z-8)>&dcTGKFML%Ma!m!q7V4# zKI>ZY3!VA4*KW|#L4IDO^s4r+T55i&Lo*QpdXW{s`DsaZIBl1e zg45T5%Wqg&omvUz=1(sAbVQ$5kDUv^7qpvFK@vOWO9Vy3H zg=@2XXpS!pUw@b+hMN$;#?H&3$2K-(^SrtaE`+>C$AI19eGXS&@hPfH4xeuIfWTWl z=(}X~l&D*$`qI?S@Ude3TQgJaL2y7*JDK9gH3+OMnIw(<7t)qm%)L^ty;3pCia?9{=!eOOUoWRb*C5zW)ZAAD|A68OL zS&4c&^fP1lcRmxm&Ww3PZ-KXnlO&B`7O;q9nuImfBH5!aWlfxr_@tYAB<#|lF-;!# z1w@%YaVmC5cAl|GVc}3Ounz&|&HU6eVJ6^&GGRyHul3g;4RBpzoywkS9zj!2xE34l zV;DMPE%|Ns)|>eyAq75gY1&vGQFFZ{^LTRz%KwX#cMK8*X4*u@wr$(CZQHhO+qP}n zwsFR`J#*%sz58w5`raSAx3(&kbXVn9I{l=(^CXKoZdq;vNatfDE}-KM$j%+8sR`uy zG^L*rQV7qb0r8G}MjGcSss-f0j@rXC2cjulq**4L_6_gcV|uRMGa~!Fd4IvWe`ZO+ z;>UxnBL~qL@)2@AS<$XZ!LmCxAoWP>)!3A2ddD=rZT!kI$`OZMwyTE+xcO}5z9IQ| zhgg#x=H?@=KDawPk}|9bJL?`e)};?WPjGd3VvU}`^o^ct^$XC*4lm(IA)YaLErs~X z&!Q)OAN&8ibDzCmPC5Yr066@MDyaYW&h2XFVrgqCX=i5tU))3`Yk6cr6yD{uTQ^N; z6wyKShz0PC6GA>9Lc#^3u!w7*k32benRKzo`LW#gY62_@+I~x&;RO9oaKG z+|IY1XL-4M{(j#;4Dsz?Nf{FRaAYS*Yl(~rqH<))SY@s~3xtu2juo0Mr&pjNBLLI~E$gnh>zaT;b3W=-2LjjI0f=buw? z8;OwV(~$H%%JOAu3Q*=q(D~5NjvP6;J7)*>1D3RS0jU*(7pTLjn!_vvn?x#fXKQU+I5|4FubCXBw zWnm_`o}Avl&D#m#cNt{9(}h{qTU+3}!+Xf=Y*gj4g1TXPO*Y2|_zwd)3^QiFy>*** z>=e478>A_Jk{`5xE3u)BU80j+?u;?g`WDt3SOi7|QHhr%LJgL5wCfv)>&_3YoC}2&<0`R^<3DRIa(b<`91&ZoiT1!Bwq9ec*KuYW}R!@QYOYCErOa9SG{27Q4TyP4mj`8|NGWG8er?{{Xu40t5p>UJ|q*SWvSC9%Um5t+1$VEBaQoRvrLrc;_dHHzCNxG$#w} za=F>+^+tcefjyhxoDxHKt=87P(sIvR^Cl-INtQf0H@eO3bnd_Nz1#gVyXAjB)do!7@S1Rk9&D%}dX-d>S1($p}WZDSQ~Cxtm>l|IH9?%GDVoyGhtQ>)OZ z5)M2iO=oL^5R`V)Uv`vXpIQ@p}y- zEU#D;D#je9Dp6IQMHTI;Q47s$3q4xMyLM62P&Hf>((OztL^h*g^viixm}9U!!!=SD zsu6r2vXjf`!JoRA<+8H-O0(*6s>od7hx`FOm|?y1Nmzr~_+l`f15c~NblAwJ0Id6} z-jg0Y3HzIKpLgZ!vd7kvv{#2GC)mGJ#F}Q2I+csrwjF6Jm*sFFG*!tyC1Y97E1LVj0Ta^ZVs2fG5enL5iiGwBRbT zOE9aLM^7R^Hd(~ovs+~el~d+JbTQBp(p!FSzQ%Y-2*LZSHJ9jg*u5grtke>NODBrF zteE1pB-x(>#}h|RkX&B2a90t$ef-&RCeFiu`SFxjPD#cO5E-6t6O^}fO!}xh$t$7X zWqD-My<>nP*(AjaNU1|a|A67Ke}`D)Lm<2#2kc^&q)+$^Y*gv%Qv37+*!8;b!zxti zo#`90{X9!z1v_?cS=0M7!*!Ijz|R+;-uvDTWWT zl_zSCyCsJTz2V3@M#(M{Dw!;nMWXb^lINJoly_@>5mk6ZA2X5RHPKBrf6CeAkC(1} zDfoEzarq!=z^gZq3UD8Q|7}U|J}Piufd8#Y@Lnq5Fa!UW2f>FGf#(?99}%Jt4Fc~q z*g9}O9eA+(dp}sd?uc5Sb=xic%PdOqUXLk1M(2- z-uXvFhrj*caClUwc~B?VuTDSWYMo7|7;jyNL49Wae~^uL!>mV+vfxj#9-V&#b^O~7 zxXv7DL7ZW~I`I(JhuL%-qQ3jb9e)P(dwS;hR_ zJYgDUk6RmCa zKoFr(vIT6_t5vU6x3z68f2mlddj6fAxt*JvYm)T;xXEU>-+lY-yYoE@CWq(miH|Ug zK<06Q!ksDw@(Kzk_w=9&_Zyur=f%jIEH=O3%;TLOuJ?S0g{Qy2Cra)oS)T6sMa}fP zDkS0>A*nxIygO&b(@VdAg->0`?m45)^t&rm^2*l#OR$X3%aXWzkj_8(Y!0uw(Ea_0 zC;T01?w@*L&-9~P=I>#_g!{O_f8h)N6V1234)1(U?B{n~DEVxU$Cr4)FY`(X>@!C6 zcU?Gt8NJ6XV?9m)MG!#{B0fO`>^)k>2UW9a;&p+?Op#C|FF_P;LbQ&Cr)eTNl&E3= z{ru@utzs~sE)=+sHYjR)-J9JL+gIMo1w#Z(01ic``a@$_lUO;h5+=guNut|WfK^gJa?OB?)B@*gNr3YK4WfTAB(kRse7!v3B5_b?lFwTuN{qf7&yyOOuV_C6R=vy-rv9Z#{)FBRu(O1 zbYd-*^A8eBStzJ%mFyiD*h7J+gU#oU&BNcnw;c}-k39&e4v&i-V)KcaQ-c(eFANm> z)nw>y;aMy^`|vY_)E0JU#Eivcvxyporg`O}4lTruuffXs^!w~7`CL5HW>$u-2=RRa z2tZPoW*Tc|8>87@D+U_S?~Sf1@*CUjfOOU!2u)oyVuU|L?zPIpvvK>>VE~euR!&Ps zQ5iH~M%~QWagj>or^@iJZX(O`Ht2A}QUakdNf;lX8kcetu%10g%8qjp9-GAL#)lc0 zzH1VOH6^nIyo)`&Oue?5-4e^&IWG_&AgGk;%iTpU<}GD!Wb5UNgsuz?lCC6RqdKu+ zeu*Dh2<62!trU`a*SWFYz<~LeCp@YhYv_yMSvRKKdwGQ(g`X84iz+f` z9}z(sDWmY@g~zbu)Mpu-J+=6dUJKZ_*aF$sX2{EsU2AbTJZhkbbc*gaSK`w!+B8bR zgst<~YJ&|fq9gcgV5_QGb%YpMKYs-_rZIKT0wSAZmL1})a17gP<0)H8`^fyLj1>gPl`8#!ERHS1p;M;}I@GU%d#dfq^Y3i(_k6Wzo_ zul5~fDi_i(sG(@fNTFy?3RBYt^m?h&S!Pr%P-&IUfwrK^6+{Xtl+KB^suoCjbf$(+ zcytDb$-H1zxqM$#D`L|K(?{p4IZ+<%4m=b^8ZlxYt0EX(T8YM%j)JI`-l>^)D;2->vHP<3WN0 z5pWu)BLvQ1+j5U`>{=L#K0a3yXr@pY6>*58okUd@*hE#Ls62d4{RLL353W+tY)Tg~ zSLIYk8aF_-->8eURv@wv#M^{O$J7eZGIV8(ob^T3r;VD3$|AHv<%*Y48B=AI$Ax)q zlSf%ZS?`&X;s3CK(wbBM4;A8Z<%9U+FFoj5uHD?m3QvewIU zjnmk-H`^ML)VA@@cE>WAXI44*8R?6IT^HQIhIkdZH{$q#bE}Kb+KpngLvd)w3P=b6 zMKGUG9S5r2tFi}~mhE}0mRc&*Zh1c2G|+NV=nA!Gz1j9meE2*fdc|5neE2Aaed(^0 z&sUJBh<;n&d%6~VHk4x6(EoevtC( zh_AtyuNkPpg#w#5k0B)m47ePfDwZg1SISuE;=JqU1%$5%DB8 z$DS!&ZCddr>Ps$Ej`iU7!)<$$`{}m5*?p&N@2c;w8++?V>enCnrjFuY40sS-8t?Us zz-APe81Nud_vr6)7TU2#cFpLLteRdI!Qe4nMK!xAzWRdgs57Q1pp6Mlm3U2+YNp7O zFI#8{n;WV!Do#YZ5B0=<(!xax&_2X<5hh)|DZqh58+*mr3r-csg2_d8t`8k#LV*PK zx3j5mm4!zVdc_|Uv0UwH3nCuAhp^fyQMyLZlRG~%$AF(32<+qoI}mpVA_$js5yVRcdT=A$O9Wt)M+8JV84ydc_pvh>`r+)S_T)itT;Y`t z0JHS_)1&4#WJkLz64YN8ECg|vUl%X{9j6&FsV(?ZUDl3_hY@0#O*b8nWv}t_1^DyS zl@`*OemoZB8xWkdK~KHMO*`oJ~Hz%vXFmQ%SQ{R&Wf}Mb`4<#B*kua4>ZLK;0jju*S_gBs^Xnjvb`t zzMJ3~@a2iz35UX0Wbn0}bULyX0;t)Lu0uaOU`wEwd9Y#)3Z{Ur9J!AjQf(_l+gNBe z)_5jXCzwJCVc}gPD0xVrL7@)QS%!X-@#$StnY1ZSD5(?DJEAsm2}%ry<_f6^Pe>v( zxp|O#R#N9bg7ArPaDB*t=V$ISlk?_J-#<91^MykC#I&3oFT?QB?l+V0=Gz|}q1O3~ zk>4{eWhcwCzt;fd?>_s~jfm?&>cmj*95LK#){XU!rE)Aw_6(-JYpEZ?kUx;AAKI5+ zW5`L=Ngo1DA!{$I99=27!PrHl13o;m;10h~a)YstTm^XeVqx|tHyJw!_kc#UmtA1k zNo+E95bi>bbT7HUu$Nt9{6V+_KLobq3cI0TGNW+Oj@Wd4ndpBT<=GqA64yLb#8z{I zq29g>>c@T}(bL4da<(74_I8OTeG9@!XL9L~i_8Z|Cs%ejz{?};V>SB#b&HI5H|hnb zL02|t)nMzN)%{{Bf3*j=nnlsjmE3X%q^1rtGL`BIz6cAz{wd zzz4c2M$xEUll(iN`(;)B8Xo9M0;*=8^x6xz{kxDW-5DI6BCVN34w`-&{3*;byl5oxWZOzWt_FP@yCZL&gCbiWc~9eZC?_k}F0oUA`=2$x53x z$3jvQQfpR#xM$Ha1eI%{iI=3QBwlOmXN21Vi%Pzd_TyWF5 z@XBN1&DXL6WlJB@wq0;D3c2MZyuacWFRMMf)J83-Ew>!G#b>kZRv-8hfr`h^9Aud9 z&A`GLe1HWq+)6h{;LyHpPnys@m`%@$dw*0G+yaq%#^aLr1UPOx4wy9uf5fqURs5iU z-@AvUvK)3!A~F#K)3@)$!!r7{>Qo`IB+D_DU8&Ip`rv>)n`S2t^GC3DDNbW81GfIu zFZ4+~yf%53_`{r;KH_Xo@nmmN3#v)GU{^5uIz2yUgJY9J@9Hyn-y#r5eR zF6i$1XV|w@NBS@@i+?FmL=hIAwZ?iw;?NkE80r%wTQY^khP1KvC@9FQq4+=|aJe5sdet?B-N9V0A;RjxctZ znFF@r3Cs(ETV$8*hhVYcmy!xQmXPsO!4an(@BGezrs^T)d(OUv`_jOAhv@-hpIHV& zHQj^kIOlycjK-)6U`{ zk02)_F}b=)(n=a|C7R4M7TUezHgb=b&PtflZVRglECdgs8-?Z_rgrT};|wlT*VSrJ z*MkX({ZNYL&kPP5igfJlWEu_C&X&q^QxDWY_9}$ShAC=A|RZcZF&K0ZD z(Tw{IXjpf>FgZp-cUDFK>F`RKsni?Y>a>E$CAl23$3&}!m_T(4_2E1}cf<)%_|~9y z(JFWA!d{e|BsW$_z5LPJw~U%us%1wdZLUYFi%5hVXq93-q8&U`cY;h-FaC^_+MPL< z=RW9F1lnPHr3rnV`2WYpUH5#QK)!$g0KY&006hP{eqaAzB`1x4ijt|JiK!C_o3^a5^a^56u&jSka*sKzZDO! z+lVyeVM(4&XL}6ECePNtzyqMxnk0(O3y%#ahna*w6)aEUFp^GYwZl|qTS$j(bS*tU zHmoJRiM0S3L%SYC9jI%fz6mp(bWxd(=UUU+&>|R8j`3DvZyXlU{nQ`xJd(1)mpDtg z3Dv{+-@Z_Hagf}Pb)*;5+>G0&5**de?{_!wQYqK*N0Rpg7jSo7(w3@=XHF?Zg+osl zKONV9MVQ~Dz;2`$i$iRf=Xg{XIZ7An+=zI0#v@;Wk(Fu)b=O;XYfc#gS%&|5G&3Fh zb9Y@rnd^MbtY{>bGpQP{r^u1>GMj%NF#T z{NJf4QknU|hu}4%bW(2eI0jBvU!NVRQ^@vTN(3Yb-WFlN!uWy@FO2VN1W9M)mP`mo z4E+Ca3E)qL3r!LL02NaJ0IvVbwfmn7)vF8XgCe@-U*F~3#cU}g!2v@A;}k*yB7%U3 z(s=?Uh=g!&lq54WU_v%0LlEfNt09l#_5d*Y;-(`y8ca~sR2N-$=5^(jf8M26eS7JZ zaMyd8Cr6%%bDbprKw?`oA&#_on@U zu_ZD9`U?m{2vO=4LPyc#2wbdmF)q(hEKLF)u!(tKy`h!Sc9ulKE^k99iIV7lq;rvY zHOQjrH}w{kpAVJnb)O%GaHRJU`i}2Q>8bfrKtC@I8R%&mKt7+c0mJSedO7N#<31L`s7ze|G_CSlmIT|fuv74B~RcTGc05DT{A3W_?eq)Phr-m-o}6#$mXAqX978v5um>>$w)bB!5YF-C^YG_82R$d5(!Xoc_!|9binB(c0 zKAE-A%sma^H-CorUhms^zir|DqrD92siPNlM_?7F-&DgiX5YAUSG*52>%MC4pF&}D zhTmGl-ck4FSw`wV{L%>LPQN(AIM%7>kgwhk*nJ3t=ii35|BQi#btFU`5((?fyh+0} z=G~=Z9WwRVGu+Gd*|Xd`-EP~%_C)9VoA29x_e>6Se|$Ir&mWyp!~B_>SI6qe%dcm; z$Mf5@iJ%4BogS@*b&REJ^D^uoJ+g-FnMdenA92+=@bYs7p5C#D$aZmTrn6fdt%cB3 zCO+^Wz@d-*9B!PFXyHN-WiSsN4m@8;;75ZVkr>lgWTaKNsD~Xb4?i08NYFo2`c%j( zdaUV8v{;q!kL~yIG%#uPS0&(KLW>v=KB(H5FfcLEm7P6LBz=t@eQqGwuZIu;Z*MaO z3Od^`;K0a_D1e#P4k?g}RRKZhnuiSoezK~b23l0|*NoUTnT<{P5{~{}B;ensUwwZh zz~p-EZwklC=e{m@35mTE)|yhEg8&mkB?mp4E?->>2|D@9fvIK6sv?)GeOn(JTLTGt zd9H>HA11b@8ZNfB5++29t{#56?AynWMI7p^{;vKZ9`=1ul}P$Pfw^#sT^U-FlOP`8 zX=UOXq6q$nC!!SI{KTHO=$PR^&~LM zg8`|`tM~Yw2BscHTrHe@T+&vPHhwOt4l}njMl!3v5?4MZ>cml(1fglCO$Hvc3Q|6# z814^Jb?N}ssjx3>Yfv+S*IHO{;G={pM+cdL;$?jnR;B4nZxztPB&8VuT0o`0mScXw zm7IRL2vK1Gf6oMd6{%`;xN8(BxD^w7*vfTOo#LJrD7%H4MsHiUnUnd|5#X1jNY$VN9@rG2uz-dL@g%?-PtzFW5CKr%)$u%-BsJ!2A(k*t*9!TDmP8*W}3RW*pTY3 zuF6da&Xtv*0nFAxi-I9difgy-32WL}>DFV$EYfM>MLO~35us)lteQGFm5o|h*+nfW z=H}p$APZR%kw5hft^_exDUFnWzwAXZHoSstYnz}kdY}tR!YFpFeSgI?diz#<3 z4DY@zO2`mm*NIbHGgl|s$QACr@x(vc z4BL#FWHvDgEMzYV$daJNh!-)HPr8iyItMexoiqLXa+luEJ3;l#dvS^HUb>#Z!IrUstutUTDwODwoZzc<4-miCP?&nqzrl-VY6LfXI6*+} zHVlj0VO&OWkFf3Pm_>1q>ZXWc8{Iji(^`RZK*;?;Wa=i>Q??2w%;bM@a4Vzsar9sH z(66Ixi}t2?EFbDM!pRne#O%+b*|C7F78k2JZCoy(Bk{4oL_ngC|m z86kFPp~M=2)4gUH1vW~j#2ZQM+L(oh&pb4IfEWsZb9+E=LJPyR*5^4)9(e|>+0kWd z7r%ATceSOtrG|e0?rZw=7(nqJ!I$MhBUhUB`Ydm#sAwo6YG-jjoq1SYJu+@YBqc@3 zsxFksaN3JG&DQMlSV8eeihqds*+lUkWee$()m9@Nw7Ps_Sr1z|D)SKf4js*38C5Rx z(BcVpkkHQ7>GDYX`kO=fmnx6^YaVXMCsvn7pmmQ$RQkwtmq#eR z9_y$zj0C;=O9Q=yEl%UeRoQ#CM=)4{Ch(u55)@Hj(Ls%v?C7m8CcaKlg2{cN2)bR9 zSo_RF+XpyUG3HptT}ex;cio~a4|w!UjiAz%UIAU%f*eUrB`#0Fi;L1^`TNAji>IUaKah~HZnTN>tm62peY<;=K(LLFR%y)2p8shl% z%#~4;{Ak>=cOf6ksQUNE*7x$rU`L3=>PT$npT-lGCs`e#p^gywr7rF2`4q41vy6;j zU)cv(`Swr=KJn`3aHElN`v*m+N_CYQmQnXZeF!2XX2vK+H)#Op7`ZxbWDQ)RBr&2M$O3?yCU?-^S!AlKu^%1QlqON+B6CFSdMSL&bD zL4{sQtPjZ-@#*wzCe& z7Sz;giq^%1N{c3OLVw>9HajXjzso$79O}I>8PW7yYG~0Zb+8K2U_hLW11f7HfXYUe z(do+YRavcI8B$%w$wszBODC4g`ZLlEl`hH_EuGM8N`1!ETPZNnL|P}Rs9rD^gb;;r z8oEb7s}?o`s!SV3WNJLhc!hdzhwvD!EWRFM6DrNe&N2Mx+BlKQ@J*ymtgIQbxxvn| zCFKiI`ZV#4vEA=RZ4DuHb$;d{9;MIwX*aTrZ9ifuyleoHt-S#DtSLe%I3X>X>w3c9 z!Ku&3Xt#+SCRodGmRe$eUV?P^%acMLDl^+yp2`G$*;4#BV&Od8F{|oid-$sWC(bmd*Bm;bn&6o z!K$r_9L6rEj!GCMundRn z8_xt`Gwm1ZqTePTJbw$ssi=hq875DTip!J+YJPC-m{JdPx=@kJlqO1@?{$R`afE94#IQD*?^(k2L)P%HzgHiiNMV)<76Cbs%5WHsm zkyVq(EuvzgrqvQuA;@t`^w~*v5buo8yM=0J(g?{0*RRn5XMxDv3`b(C1pa)+3eFo+ z#^dpz=r2e~JVbrH4_zklNUD9KqFxVMSpgYRp}1WpjKKLx_9MoV#PV{k0#5!q{L$^= z!P1<)PUZ(!9Ddvv!5k~c&r=}KLDkQTK`QC+-I#|a4p$mY6}f@qGFCsRJ!&%JN1bq( zTzQJe1#>T{)XN(!OJ&6!N-kBNSb9A9dw$GuCe-{Mu~q6>7ZbQ_qG6lrU20{@ww_D- zL;=)Ife`&s4J6s7p<=*3O#M8BbkOudZ@{+8JiJ+-Fj zI9_g_hO;VL?|@IYOd&^{zDYtZAB-60QXm)gfTvS>^_-D1YcZCoIqA_uT(%J;?8>n(=7}SLYv*g# zIT6>POw}G@_C8&!F$n{%mdq_x2e`b=ZD+Hrp=1Eb#UFE|Kge-*`x>9lv~x!TzZ=aX zLe-O{+FrOGd=Mpo`^E7}eT)d}SwN#}f_68?A|HR8XYAuPI>qJ#LoP$2Aaf-mSROyy zp~mHF#Z`~B+SxT1h-$qcIWUz4#jUQ5$0+44fq%o2MZ6{8(hDF(H*l^STi{CCpGgbg7bOWVSX@s*w1 zuK~=h@5Ojp1WRd7HR2>Tl-sT0ioQV!IW+MqR=P^YOU-`aEXm~EIOfxpYOL|2e?G-v zaXa!3ZgKlPBxKf?%(XEucW7Y9UF^9Pun?{%C!NT$5MsH9tw6#-t8{aXW@W1LsSlUO zWn~q_dab;pDT95mM^xSHoLx@2Hmy0Ej1mPy1H~e*NCOa63o`1JkzY3lKdclD2-Izie-P;Ji zqd8C5mS68K#!weVb5*FoXED`=T;dP(pcnz{gAMTkzca>QKXXk254dvv;AxFH`mh{FT( zCB1yM4?soPbUYkbaCo4iCisjU7i->L<}UW4)II>w-l!>Q+Hv~+$K;k`d`&UFp~$hq=9a>uomi?<6lzMNxDR1j4gMZ)9hR8unPIQ} zRcCt>?kl0pgSyyfS@ebTJTi7Jt$Ftm; z&%!M`NX#*X*NQwTROY?qJLn*kh0Irr%0q%`qCEtsc==vp2;7u1QZws1Vkt&OeBYwG z5cWCj08{0jLpBnO!vwknod1lqU#}BUQz>@<+FC_53DOxNT zCmD>B4Aw~o%OsOT+W0(o_~Y7cc7_LPe9MeaMvK=4U)&5&^c8mt;HNEi-2)89HMz>) z2@Iy;T_vNKv2emo%Xm@`8Ls(jLH+V8V%JZ~p1+v#f%D}=8UuQ7!cV5;4wC^Ue$25+ z{3r)6*4c|??qZRnT>MA}Ss0vAecbpl%hifUu7Ml1peiO`GFOUP0c+q4&xBJvaYih( zqqOs$4Odxa9A%ktwB@1AysTaGX#CKT5+f{>+i?H&6lOT@7kM~tG*V3%q)-ePP(iGh zr`MrJ?H%M?GdzC13GBq;*r$Eqpxf{sX~<$ zp&j{g+}nv~WCdswWzfN!W?YE9$%G;HM8S!pGa=5iMF~X! zZg!23<-*C5FJ}0GA-I9Eh>&XR$PiO5mDmBQmc6s(8&_WBegLM5ACg?TQll?hh!i(1 z!Ny-QnaR9lDkqW3S*!}CeDiO!OkAdDa$dm?%#LeLU&2I^YSmE;K4JByMP2~&b_N77 zmcjAPjcf>UmTX8&x3WA)Nh+#5(Jf6N3=d}0g9=9U-@06gW(POyT&z_9@!i!AxzfE= zvGTcsQ|n6Q>PqF8mCDwY%I2;%WoHMwf0K3qjJI4h#a*XN55TPakX~1nDrr|L zt-ITlMLFtYe(be~k^k0xE0Mi-^tw zIN$-6p-@*1cbikqS3vfT7=VuyfbU;V4$yb21t8V10+)K~JRtYxa+xA{`_s``chI^v zm@lzR&(afHSHZv2NV3yJ!s%gI;!8-^)H+{`wplRa6E(sEigGHiLP5^aHyT8~RBDw^ zdQ~wul6);^c4)LIIS78ihO@qy(C|${t-)KD@5k$rYE)lrv9J=fre6xrjhs=jT5$CqaKFN5Ggj;U)00VPA>Nwz6hT@dGSUF1e zL;g#COxb3bo`AKd=_$iPo4}b}M$?I2W(RT^Y5ycVm%&$$@Wmu7;CslA`yd1@B0_ON zJ|;}isD@f@!hL3HT={{8)8<3%U1m}-jGBoM*n4i_;aLrgt{FB*AeLdm%P(*XfLS|; zb#@eZ$5ORj%eHjIo;p`j%JaSFgT>YCMY^zkgmpqsydHhJLFaYMnjDx`yP`pxV@}Rw z*#sJvq1zPLFa6-QL5gibrglHrQ@ZwC(jGPothYACa@Q_H7-AN;e#see_B^Uli~a@+ zLw7-X8}tbz=50cWG4&Zop3F1yV?7`osp2~b2Y%S|kSo@y;>>LrXi1q#ulRa~M7IQNfp*4jm8H|H-@f|}lFDd0( zIH_%)l4Jv*oD9pJByc$ih*u*ZhNBlSjTDQ%K>lx9{uEXLμVJSr_eC{_W}qDK*p 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

$9KdEZgXOFy$e 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%0D6W?hyK{^AF<|S~m-esn}sB{UHz{ZV(Fz{EX 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�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