/* 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; import static org.digidoc4j.testutils.TestDataBuilder.PKCS12_SIGNER; import static org.digidoc4j.testutils.TestDataBuilder.createEmptyBDocContainer; import static org.digidoc4j.testutils.TestDataBuilder.signContainer; import static org.digidoc4j.testutils.TestSigningHelper.getSigningCert; import static org.digidoc4j.utils.Helper.deserializer; import static org.digidoc4j.utils.Helper.serialize; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.URI; import java.security.cert.X509Certificate; import java.util.Date; import org.apache.commons.io.IOUtils; import org.digidoc4j.Container; import org.digidoc4j.ContainerOpener; import org.digidoc4j.DataFile; import org.digidoc4j.DataToSign; import org.digidoc4j.DigestAlgorithm; import org.digidoc4j.Signature; import org.digidoc4j.SignatureBuilder; import org.digidoc4j.SignatureProfile; import org.digidoc4j.ValidationResult; import org.digidoc4j.exceptions.NotYetImplementedException; import org.digidoc4j.impl.DigiDoc4JTestHelper; import org.digidoc4j.testutils.TestDataBuilder; import org.digidoc4j.testutils.TestSigningHelper; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class BDocSerializationTest extends DigiDoc4JTestHelper { String testContainerPath; String serializedContainerPath; @Rule public TemporaryFolder testFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { testContainerPath = testFolder.newFile("container.bdoc").getPath(); serializedContainerPath = testFolder.newFile("container.bin").getPath(); } @Test public void twoStepSigningWithSerialization() throws IOException, ClassNotFoundException { String serializedDataToSignPath = testFolder.newFile().getPath(); Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); X509Certificate signerCert = getSigningCert(); DataToSign dataToSign = SignatureBuilder. aSignature(container). withSigningCertificate(signerCert). buildDataToSign(); serialize(container, serializedContainerPath); serialize(dataToSign, serializedDataToSignPath); dataToSign = deserializer(serializedDataToSignPath); byte[] signatureValue = TestSigningHelper.sign(dataToSign.getDigestToSign(), dataToSign.getDigestAlgorithm()); container = deserializer(serializedContainerPath); Signature signature = dataToSign.finalize(signatureValue); container.addSignature(signature); container.saveAsFile(testContainerPath); container = ContainerOpener.open(testContainerPath); ValidationResult validate = container.validate(); assertTrue(validate.isValid()); assertEquals(1, container.getSignatures().size()); } @Test public void verifySerialization() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); assertTrue(deserializedContainer.validate().isValid()); } @Test public void serializeExistingContainer() throws Exception { Container container = TestDataBuilder.open("testFiles/valid-containers/valid-bdoc-tm.bdoc"); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); assertEquals(1, deserializedContainer.getDataFiles().size()); assertEquals(1, deserializedContainer.getSignatures().size()); } @Test public void validateAfterSerializingExistingContainer() throws Exception { Container container = TestDataBuilder.open("testFiles/valid-containers/valid-bdoc-tm.bdoc"); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); assertTrue(deserializedContainer.validate().isValid()); } @Test public void serializationVerifySpecifiedSignatureParameters() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); Signature signature = SignatureBuilder. aSignature(container). withSignatureDigestAlgorithm(DigestAlgorithm.SHA512). withSignatureToken(PKCS12_SIGNER). withSignatureId("S99"). withRoles("manager", "employee"). withCity("city"). withStateOrProvince("state"). withPostalCode("postalCode"). withCountry("country"). invokeSigning(); container.addSignature(signature); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); Signature deserializedSignature = deserializedContainer.getSignatures().get(0); assertEquals("postalCode", deserializedSignature.getPostalCode()); assertEquals("city", deserializedSignature.getCity()); assertEquals("state", deserializedSignature.getStateOrProvince()); assertEquals("country", deserializedSignature.getCountryName()); assertEquals("employee", deserializedSignature.getSignerRoles().get(1)); assertEquals("S99", deserializedSignature.getId()); assertEquals("http://www.w3.org/2001/04/xmlenc#sha512", deserializedSignature.getSignatureMethod()); } @Test public void serializationVerifyDefaultSignatureParameters() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); Signature signature = deserializedContainer.getSignatures().get(0); assertNull(signature.getCity()); assertThat(signature.getSignerRoles(), is(empty())); assertTrue(signature.getId().startsWith("id-")); assertEquals("http://www.w3.org/2001/04/xmlenc#sha256", signature.getSignatureMethod()); } @Test public void serializationGetDocumentType() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); assertEquals(container.getType(), deserializedContainer.getType()); } @Test public void serializationGetOCSPCertificate() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); byte[] ocspCertBeforeSerialization = container.getSignatures().get(0).getOCSPCertificate(). getX509Certificate().getEncoded(); byte[] ocspCertAfterSerialization = deserializedContainer.getSignatures().get(0).getOCSPCertificate(). getX509Certificate().getEncoded(); assertArrayEquals(ocspCertBeforeSerialization, ocspCertAfterSerialization); } @Test public void serializationGetSigningTime() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); Date signingTimeBeforeSerialization = container.getSignatures().get(0).getClaimedSigningTime(); Date signingTimeAfterSerialization = deserializedContainer.getSignatures().get(0).getClaimedSigningTime(); assertEquals(signingTimeBeforeSerialization, signingTimeAfterSerialization); } @Test(expected = NotYetImplementedException.class) public void serializationGetPolicy() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); String signaturePolicyBeforeSerialization = container.getSignatures().get(0).getPolicy(); String signaturePolicyAfterSerialization = deserializedContainer.getSignatures().get(0).getPolicy(); assertEquals(signaturePolicyBeforeSerialization, signaturePolicyAfterSerialization); } @Test(expected = NotYetImplementedException.class) public void serializationGetSignaturePolicyURI() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); URI signaturePolicyURIBeforeSerialization = container.getSignatures().get(0).getSignaturePolicyURI(); URI signaturePolicyURIAfterSerialization = deserializedContainer.getSignatures().get(0).getSignaturePolicyURI(); assertEquals(signaturePolicyURIBeforeSerialization, signaturePolicyURIAfterSerialization); } @Test public void serializationGetSigningCertificate() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); byte[] signingCertBeforeSerialization = container.getSignatures().get(0).getSigningCertificate(). getX509Certificate().getEncoded(); byte[] singingCertAfterSerialization = deserializedContainer.getSignatures().get(0).getSigningCertificate(). getX509Certificate().getEncoded(); assertArrayEquals(signingCertBeforeSerialization, singingCertAfterSerialization); } @Test public void serializationGetRawSignature() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); byte[] rawSignatureBeforeSerialization = container.getSignatures().get(0).getAdESSignature(); byte[] rawSignatureAfterSerialization = deserializedContainer.getSignatures().get(0).getAdESSignature(); assertArrayEquals(rawSignatureBeforeSerialization, rawSignatureAfterSerialization); } @Test public void serializationGetTimeStampTokenCertificate() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container, SignatureProfile.LT); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); byte[] timeStampTokenCertificateBeforeSerialization = container.getSignatures().get(0). getTimeStampTokenCertificate().getX509Certificate().getEncoded(); byte[] timeStampTokenCertificateAfterSerialization = deserializedContainer.getSignatures().get(0). getTimeStampTokenCertificate().getX509Certificate().getEncoded(); assertArrayEquals(timeStampTokenCertificateBeforeSerialization, timeStampTokenCertificateAfterSerialization); } @Test public void serializationGetProfile() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); SignatureProfile signatureProfileBeforeSerialization = container.getSignatures().get(0).getProfile(); SignatureProfile signatureProfileAfterSerialization = deserializedContainer.getSignatures().get(0).getProfile(); assertEquals(signatureProfileBeforeSerialization, signatureProfileAfterSerialization); } @Test public void serializationGetDataFiles() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); int nrOfDataFilesBeforeSerialization = container.getDataFiles().size(); int nrOfDataFilesAfterSerialization = deserializedContainer.getDataFiles().size(); assertEquals(nrOfDataFilesBeforeSerialization, nrOfDataFilesAfterSerialization); } @Test public void serializationDataFileCheck() throws Exception { Container container = createEmptyBDocContainer(); container.addDataFile("testFiles/test.txt", "text/plain"); signContainer(container); serialize(container, serializedContainerPath); Container deserializedContainer = deserializer(serializedContainerPath); DataFile dataFileBeforeSerialization = container.getDataFiles().get(0); DataFile dataFileAfterSerialization = deserializedContainer.getDataFiles().get(0); assertEquals(dataFileBeforeSerialization.getFileSize(), dataFileAfterSerialization.getFileSize()); assertArrayEquals(dataFileBeforeSerialization.getBytes(), dataFileAfterSerialization.getBytes()); assertEquals(dataFileBeforeSerialization.getId(), dataFileAfterSerialization.getId()); assertEquals(dataFileBeforeSerialization.getName(), dataFileAfterSerialization.getName()); assertEquals(dataFileBeforeSerialization.getMediaType(), dataFileAfterSerialization.getMediaType()); byte[] bytesBeforeSerialization = IOUtils.toByteArray(dataFileBeforeSerialization.getStream()); byte[] bytesAfterSerialization = IOUtils.toByteArray(dataFileAfterSerialization.getStream()); assertArrayEquals(bytesBeforeSerialization, bytesAfterSerialization); assertArrayEquals(dataFileAfterSerialization.calculateDigest(), dataFileBeforeSerialization.calculateDigest()); } }