/* 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.xades; import static eu.europa.esig.dss.DigestAlgorithm.SHA256; import static eu.europa.esig.dss.SignatureLevel.XAdES_BASELINE_B; import static eu.europa.esig.dss.SignatureLevel.XAdES_BASELINE_LT; import static org.apache.commons.codec.binary.Base64.decodeBase64; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.io.IOUtils; import org.digidoc4j.Configuration; import org.digidoc4j.DataFile; import org.digidoc4j.DigestAlgorithm; import org.digidoc4j.SignatureProfile; import org.digidoc4j.impl.bdoc.SkDataLoader; import org.digidoc4j.impl.bdoc.ocsp.BDocTSOcspSource; import org.digidoc4j.signers.PKCS12SignatureToken; import org.digidoc4j.testutils.TestSigningHelper; import org.junit.Before; import org.junit.Test; import eu.europa.esig.dss.DSSDocument; import eu.europa.esig.dss.DSSUtils; import eu.europa.esig.dss.EncryptionAlgorithm; import eu.europa.esig.dss.FileDocument; import eu.europa.esig.dss.Policy; import eu.europa.esig.dss.SignerLocation; import eu.europa.esig.dss.client.tsp.OnlineTSPSource; public class XadesSigningDssFacadeTest { static Configuration configuration = new Configuration(Configuration.Mode.TEST); private XadesSigningDssFacade facade; @Before public void setUp() throws Exception { facade = createSigningFacade(); } @Test public void getDataToSign() throws Exception { facade = new XadesSigningDssFacade(); List<DataFile> dataFilesToSign = createDataFilesToSign(); byte[] dataToSign = getDataToSign(dataFilesToSign); assertNotNull(dataToSign); assertTrue(dataToSign.length > 0); } @Test public void signDocumentTest() throws Exception { facade.setCertificateSource(configuration.getTSL()); facade.setOcspSource(createOcspSource()); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); assertDocumentSigned(signedDocument); } @Test public void signDocumentWithSha512() throws Exception { facade.setSignatureDigestAlgorithm(DigestAlgorithm.SHA512); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA512); assertDocumentSigned(signedDocument); } @Test public void signDocumentWithECC() throws Exception { PKCS12SignatureToken eccSignatureToken = new PKCS12SignatureToken("testFiles/ec-digiid.p12", "inno".toCharArray()); X509Certificate signingCert = eccSignatureToken.getCertificate(); facade.setEncryptionAlgorithm(EncryptionAlgorithm.ECDSA); facade.setSigningCertificate(signingCert); List<DataFile> dataFilesToSign = createDataFilesToSign(); byte[] dataToSign = facade.getDataToSign(dataFilesToSign); byte[] signatureValue = eccSignatureToken.sign(DigestAlgorithm.SHA256, dataToSign); DSSDocument signedDocument = facade.signDocument(signatureValue, dataFilesToSign); assertDocumentSigned(signedDocument); } @Test public void signWithSignerInformation() throws Exception { SignerLocation signerLocation = new SignerLocation(); signerLocation.setCountry("Val Verde"); signerLocation.setPostalCode("1776"); signerLocation.setLocality("Kansas City"); facade.setSignerLocation(signerLocation); facade.setSignerRoles(Arrays.asList("manager", "potato expert")); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); assertDocumentSigned(signedDocument); } @Test public void signWithSignaturePolicy() throws IOException { Policy signaturePolicy = new Policy(); signaturePolicy.setId("urn:oid:1.3.6.1.4.1.10015.1000.3.2.1"); signaturePolicy.setDigestValue(decodeBase64("3Tl1oILSvOAWomdI9VeWV6IA/32eSXRUri9kPEz1IVs=")); signaturePolicy.setDigestAlgorithm(SHA256); signaturePolicy.setSpuri("https://www.sk.ee/repository/bdoc-spec21.pdf"); facade.setSignaturePolicy(signaturePolicy); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); assertDocumentSigned(signedDocument); } @Test public void signWithBesSignatureProfile() throws Exception { facade.setSignatureLevel(XAdES_BASELINE_B); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); assertDocumentSigned(signedDocument); } @Test public void setSignatureId() throws Exception { facade.setSignatureId("Signature-0"); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); assertDocumentSigned(signedDocument); } @Test public void extendBesSignature_toTimestampSignature() throws Exception { facade.setSignatureLevel(XAdES_BASELINE_B); DSSDocument signedDocument = signTestData(DigestAlgorithm.SHA256); XadesSigningDssFacade extendingFacade = createSigningFacade(); extendingFacade.setSignatureLevel(XAdES_BASELINE_LT); DSSDocument detachedContent = new FileDocument("testFiles/test.txt"); DSSDocument extendedDocument = extendingFacade.extendSignature(signedDocument, detachedContent); assertDocumentSigned(extendedDocument); } private DSSDocument signTestData(DigestAlgorithm digestAlgorithm) { List<DataFile> dataFilesToSign = createDataFilesToSign(); byte[] dataToSign = getDataToSign(dataFilesToSign); byte[] signatureValue = signData(dataToSign, digestAlgorithm); return facade.signDocument(signatureValue, dataFilesToSign); } private byte[] getDataToSign(List<DataFile> dataFilesToSign) { X509Certificate signingCert = TestSigningHelper.getSigningCert(); facade.setSigningCertificate(signingCert); return facade.getDataToSign(dataFilesToSign); } private byte[] signData(byte[] dataToSign, DigestAlgorithm digestAlgorithm) { byte[] digestToSign = calculateDigestToSign(dataToSign, digestAlgorithm); return TestSigningHelper.sign(digestToSign, digestAlgorithm); } private XadesSigningDssFacade createSigningFacade() { XadesSigningDssFacade facade = new XadesSigningDssFacade(); facade.setCertificateSource(configuration.getTSL()); facade.setOcspSource(createOcspSource()); facade.setTspSource(createTSPSource()); return facade; } private BDocTSOcspSource createOcspSource() { BDocTSOcspSource ocspSource = new BDocTSOcspSource(configuration); SkDataLoader dataLoader = SkDataLoader.createOcspDataLoader(configuration); dataLoader.setUserAgentSignatureProfile(SignatureProfile.LT); ocspSource.setDataLoader(dataLoader); return ocspSource; } private OnlineTSPSource createTSPSource() { SkDataLoader timestampDataLoader = SkDataLoader.createTimestampDataLoader(configuration); timestampDataLoader.setUserAgentSignatureProfile(SignatureProfile.LT); OnlineTSPSource tspSource = new OnlineTSPSource(configuration.getTspSource()); tspSource.setDataLoader(timestampDataLoader); return tspSource; } private List<DataFile> createDataFilesToSign() { List<DataFile> dataFilesToSign = new ArrayList<>(); dataFilesToSign.add(new DataFile("testFiles/test.txt", "plain/text")); return dataFilesToSign; } private byte[] calculateDigestToSign(byte[] dataToDigest, DigestAlgorithm digestAlgorithm) { return DSSUtils.digest(digestAlgorithm.getDssDigestAlgorithm(), dataToDigest); } private void assertDocumentSigned(DSSDocument signedDocument) throws IOException { assertNotNull(signedDocument); byte[] bytes = IOUtils.toByteArray(signedDocument.openStream()); assertNotNull(bytes); assertTrue(bytes.length > 0); } }