Coder Social home page Coder Social logo

digidoc4j's People

Contributors

aarmam avatar aasaru avatar ahoa avatar andresrosenthal avatar dependabot-preview[bot] avatar erkoristhein avatar heititobi avatar informatik01 avatar ivomattus avatar janarrahumeel avatar jart avatar jorgenheinsoo avatar jukutr avatar kamlatm avatar kristelmerilain avatar martinpaljak avatar naare avatar nibbydev avatar nostneji avatar priitserk avatar rsarendus avatar rvillido avatar siimsuu avatar siimsuu1 avatar smartman avatar tanelts avatar tynisr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

digidoc4j's Issues

Possible to disable LTV / configure ValidationLevel?

For testing we need to disable Long Term Validation (LTV), because:

<Errors>The result of the LTV validation process is not acceptable to continue the process!</Errors>

(Probably because we did not prepare our container for this.)

During debugging, we found the option ValidationLevel in DSS (/eu/europa/esig/dss/validation/SignedDocumentValidator.java), which is used by digidoc4j.

Unfortunately this variable is set to ValidationLevel.ARCHIVAL_DATA per default and never changed or exposed.


Is it possible to disable LTV? (During Container creation or container validation.)

BDOC signatures with same <xades:SigningTime> after serialization

Dear friends of open-eid, I hope you are fine.

I am signing a BDOC container several times using the following steps:

Create the container:

  • create a BDOC container
  • add a file (DataFile)
  • serialize the container

Sign the container (two steps signing):

  • deserialize the container (previously created)
  • create signature parameters and signature production place
  • get the hash to sign in the server side
  • serialize the container
  • sign the hash in the client side (EstEID plug-in)
  • receive the signature
  • deserialize the container
  • add the signature (Container.signRaw)
  • serialize container

After applying three signatures to the container, these signatures have the same property <xades:SigningTime>2015-08-14T18:36:32Z</xades:SigningTime>. The signatures were made in different moments, in fact if I inspect the container content I can see that the files signatures0.xml, signatures1.xml and signatures2.xml have different modification time.

Could anyone give me a hint to find out what I am doing wrong please?.

If you wish to view the container it is available here.

Best regards

eu.europa.esig.dss.DSSException: Unable to parse file '/tmp/dss-cache-tsl/PT.xml' : Cannot add overlapping item

I am getting an exception in my logs whenever I try to sign a BDOC container:

java.util.concurrent.ExecutionException: eu.europa.esig.dss.DSSException: Unable to parse file '/tmp/dss-cache-tsl/PT.xml' : Cannot add overlapping item
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:188)
	at eu.europa.esig.dss.tsl.service.TSLValidationJob.analyzeCountryPointers(TSLValidationJob.java:411)
	at eu.europa.esig.dss.tsl.service.TSLValidationJob.refresh(TSLValidationJob.java:260)
	at org.digidoc4j.impl.asic.tsl.LazyTslCertificateSource.refreshTsl(LazyTslCertificateSource.java:127)
	at org.digidoc4j.impl.asic.tsl.LazyTslCertificateSource.initTsl(LazyTslCertificateSource.java:119)
	at org.digidoc4j.impl.asic.tsl.LazyTslCertificateSource.refreshIfCacheExpired(LazyTslCertificateSource.java:105)
	at org.digidoc4j.impl.asic.tsl.ClonedTslCertificateSource.initializeClonedTsl(ClonedTslCertificateSource.java:56)
	at org.digidoc4j.impl.asic.tsl.ClonedTslCertificateSource.getCertificateSource(ClonedTslCertificateSource.java:49)
	at org.digidoc4j.impl.asic.tsl.ClonedTslCertificateSource.getCertificatePool(ClonedTslCertificateSource.java:75)
	at org.digidoc4j.impl.asic.tsl.LazyCertificatePool.getCertificatePool(LazyCertificatePool.java:86)
	at org.digidoc4j.impl.asic.tsl.LazyCertificatePool.getInstance(LazyCertificatePool.java:61)
	at eu.europa.esig.dss.validation.SignatureValidationContext.initialize(SignatureValidationContext.java:131)
	at eu.europa.esig.dss.validation.DefaultAdvancedSignature.getSignatureValidationContext(DefaultAdvancedSignature.java:204)
	at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineLT.extendSignatureTag(XAdESLevelBaselineLT.java:80)
	at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:145)
	at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:78)
	at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:126)
	at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:148)
	at org.digidoc4j.impl.asic.xades.XadesSigningDssFacade.signDocument(XadesSigningDssFacade.java:119)
	at org.digidoc4j.impl.asic.AsicSignatureBuilder.finalizeSignature(AsicSignatureBuilder.java:119)
	at org.digidoc4j.impl.asic.AsicSignatureBuilder.invokeSigningProcess(AsicSignatureBuilder.java:81)
	at org.digidoc4j.SignatureBuilder.invokeSigning(SignatureBuilder.java:167)
	at *snip* *snip*
Caused by: eu.europa.esig.dss.DSSException: Unable to parse file '/tmp/dss-cache-tsl/PT.xml' : Cannot add overlapping item
	at eu.europa.esig.dss.tsl.service.TSLParser.call(TSLParser.java:139)
	at eu.europa.esig.dss.tsl.service.TSLParser.call(TSLParser.java:105)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
	... 1 more
Caused by: java.lang.IllegalArgumentException: Cannot add overlapping item
	at eu.europa.esig.dss.util.MutableTimeDependentValues.addOldest(MutableTimeDependentValues.java:34)
	at eu.europa.esig.dss.tsl.service.TSLParser.getStatusHistory(TSLParser.java:384)
	at eu.europa.esig.dss.tsl.service.TSLParser.getService(TSLParser.java:339)
	at eu.europa.esig.dss.tsl.service.TSLParser.getServices(TSLParser.java:327)
	at eu.europa.esig.dss.tsl.service.TSLParser.getServiceProvider(TSLParser.java:317)
	at eu.europa.esig.dss.tsl.service.TSLParser.getServiceProviders(TSLParser.java:303)
	at eu.europa.esig.dss.tsl.service.TSLParser.getTslModel(TSLParser.java:152)
	at eu.europa.esig.dss.tsl.service.TSLParser.call(TSLParser.java:137)
	... 5 more

This is the code, that causes it:

Configuration conf = new Configuration();
conf.setTspSource("http://demo.sk.ee/tsa/");
Container container = ContainerBuilder.aContainer()
	.withDataFile("/path/to/my/test/file.xml", "text/xml")
	.withConfiguration(conf).build();

String privateKeyPath = "/path/to/my/private/key.p12";
char[] password = "my-password".toCharArray();
PKCS12SignatureToken signatureToken = new PKCS12SignatureToken(privateKeyPath, password);
SignatureBuilder.aSignature(container).withSignatureToken(signatureToken).invokeSigning();

The exception happens on the last line.

The error seems to be caused by the Portugal government giving bad data to the library. The error itself isn't a problem, but the fact that it prints a stack trace into my logs is a problem. If I wish to ignore this error with log4j, I have to ignore the class TSLValidationJob.java, but then I may be ignoring other important errors.

The fix seems to be for the Portugal government to fix their mistake, but I figured going through the proper channels is more effective.

ArrayIndexOutOfBoundsException when trying to get OCSP certificate from a loaded BDOC container

HI.

I have found a bug. When getting an OCSP certificate from a BDOC container that was previously loaded from a file or a stream an ArrayIndexOutOfBoundsException exception is thrown in the BDocSignature#getCN(X500Name x500Name) method. The reason is that inside that method there is no check for the size of the returned array of org.bouncycastle.asn1.x500.RDN elements.:

String name = x500Name.getRDNs(new ASN1ObjectIdentifier("2.5.4.3"))[0].getTypesAndValues()[0].getValue().toString();

This happens ONLY if loading an existing BDOC container. So if you create and sign a new BDOC container and then try to get an OCSP certificate, no exception is thrown. Also there is no such problem with DDOC containers.


Here is a simple code snippet to illustrate this issue:

...
public static void main(String[] args) throws FileNotFoundException {
    Container container = ContainerBuilder.aContainer().fromExistingFile("example.bdoc").build();
    if (container != null) {
        if (container.getSignatures() != null && container.getSignatures().size() > 0) {
            System.out.println("Number of signatures: " + container.getSignatures().size());

            Signature sig = container.getSignatures().get(0);

            // Calling getOCSPCertificate() will cause ArrayIndexOutOfBoundsException
            // in BDocSignature#getCN(X500Name x500Name)
            X509Cert ocspCertificate = sig.getOCSPCertificate();
            ...
        }
    }
}

Obsolete values in TEST default configuration

Since https://demo.sk.ee/TSL/tl-mp-test-EE.xml is not available anymore, the updated URL from https://github.com/open-eid/digidoc4j/wiki/Using-test-TSL-lists should also be present in org.digidoc4j.Configuration.

If I try refreshing TSL with the default TEST configuration, it fails:

...
Caused by: org.digidoc4j.exceptions.TslCertificateSourceInitializationException: Unable to load the LOTL: content is empty
	at org.digidoc4j.impl.bdoc.tsl.LazyTslCertificateSource.refreshTsl(LazyTslCertificateSource.java:139)
	at org.digidoc4j.impl.bdoc.tsl.LazyTslCertificateSource.refresh(LazyTslCertificateSource.java:93)
...

Content in trailing section of signature xml

Digidoc4j fails to read a signature when the signature file has trailing information after the xml tags. DigiDoc3 client opens the container correctly and displays the signature. This invalid_signature.txt is the ending of the signature file in question. If the comment is correct for the file then it seems to be created by "libdigidoc Android".

The error produced from parsing is:

org.digidoc4j.impl.bdoc.xades.XadesValidationDssFacade - Failed to parse xades signature: org.xml.sax.SAXParseException; lineNumber: 210; columnNumber: 24; Content is not allowed in trailing section.
org.digidoc4j.exceptions.InvalidSignatureException: Invalid signature document
	at org.digidoc4j.impl.bdoc.xades.XadesValidationDssFacade.openXadesValidator(XadesValidationDssFacade.java:50)
	at org.digidoc4j.impl.bdoc.xades.XadesValidationReportGenerator.createXadesValidator(XadesValidationReportGenerator.java:93)
	at org.digidoc4j.impl.bdoc.xades.XadesValidationReportGenerator.initXadesValidator(XadesValidationReportGenerator.java:86)
	at org.digidoc4j.impl.bdoc.xades.XadesValidationReportGenerator.openDssSignature(XadesValidationReportGenerator.java:62)
	at org.digidoc4j.impl.bdoc.xades.XadesSignatureParser.parse(XadesSignatureParser.java:28)
	at org.digidoc4j.impl.bdoc.BDocSignatureOpener.createBDocSignature(BDocSignatureOpener.java:49)
	at org.digidoc4j.impl.bdoc.BDocSignatureOpener.parse(BDocSignatureOpener.java:42)
	at org.digidoc4j.impl.bdoc.BDocContainer.parseSignatureFiles(BDocContainer.java:111)
	at org.digidoc4j.impl.bdoc.ExistingBDocContainer.populateContainerWithParseResult(ExistingBDocContainer.java:196)
	at org.digidoc4j.impl.bdoc.ExistingBDocContainer.openContainer(ExistingBDocContainer.java:188)
	at org.digidoc4j.impl.bdoc.ExistingBDocContainer.<init>(ExistingBDocContainer.java:62)
	at org.digidoc4j.ContainerOpener.open(ContainerOpener.java:119)

Hello world in digidoc4j and configuration files

I followed the documentation to build digidoc4j in a 64 bits Debian GNU/Linux wheezy:

git clone --recursive https://github.com/open-eid/digidoc4j.git
cd digidoc4j
ant

and I got the jar digidoc4j-0.2.9.LOCAL_BUILD.jar.

In a new Java project I am trying to do a Hello world program to create a container, add a text file and save it to disk (without a signature for now).

package testdigidoc4j;

import org.digidoc4j.Configuration;
import org.digidoc4j.Container;

public class TestDigidoc4j {

    public static void main(String[] args) {        
        Configuration configuration;
        configuration = new Configuration(Configuration.Mode.TEST);
        configuration.loadConfiguration("/home/aaraujo/desarrollo/2015/workspace-luna/JAXRS-Murachi/WebContent/WEB-INF/lib/digidoc4j.yaml");
        configuration.setTslLocation("http://localhost/trusted-test-mp.xml");
        Container container;        
        container = Container.create(Container.DocumentType.BDOC, configuration);
        container.addDataFile("/tmp/215d6ef7-d639-4191-87a1-ef68a91b2b27", "text/plain");
        System.out.println("salida." );
    }
}

when I run the program I get the following error:

06.04.2015 10:32:32.103 ERROR [TrustedListsCertificateSource.java:528] - Other problem: java.lang.NullPointerException
java.lang.NullPointerException: null
    at java.io.File.<init>(File.java:251) ~[na:1.7.0_21]
    at eu.europa.ec.markt.dss.validation102853.https.FileCacheDataLoader.get(FileCacheDataLoader.java:137) ~[dss-service-4.3.0-RC.jar:na]
    at eu.europa.ec.markt.dss.validation102853.tsl.TrustedListsCertificateSource.getTrustStatusList(TrustedListsCertificateSource.java:239) [dss-document-4.3.0-RC.jar:na]
    at eu.europa.ec.markt.dss.validation102853.tsl.TrustedListsCertificateSource.loadTSL(TrustedListsCertificateSource.java:513) [dss-document-4.3.0-RC.jar:na]
    at eu.europa.ec.markt.dss.validation102853.tsl.TrustedListsCertificateSource.init(TrustedListsCertificateSource.java:400) [dss-document-4.3.0-RC.jar:na]
    at org.digidoc4j.Configuration.getTSL(Configuration.java:718) [digidoc4j-0.2.9.LOCAL_BUILD.jar:0.2.9]
    at org.digidoc4j.impl.BDocContainer.<init>(BDocContainer.java:123) [digidoc4j-0.2.9.LOCAL_BUILD.jar:0.2.9]
    at org.digidoc4j.Container.create(Container.java:103) [digidoc4j-0.2.9.LOCAL_BUILD.jar:0.2.9]
    at testdigidoc4j.TestDigidoc4j.main(TestDigidoc4j.java:19) [bin/:na]

I think this is an error caused by a missing configuration, so I would recommend to improve the documentation to add a section describing where to put configuration files and how to use them.

Serialization of an existing BDOC container or DataToSign from an exiting BDOC container is not supported

Hi.

While using the latest (1.0.2 as of now) release of DigiDoc4j library I have encountered the following issue. If I create a new BDOC container both this container and DataToSign object can be successfully serialized. But when I read an existing BDOC container then neither this container object nor DataToSign object can be serialized.

The following exception is thrown in both cases (I used SerializationUtils from Apache Commons Lang for serialization but it is irrelevant in this case):

org.apache.commons.lang.SerializationException: java.io.NotSerializableException: java.util.zip.ZipEntry


Simple example to reproduce this issue:

Container container = ContainerBuilder. 
    aContainer(). 
    fromExistingFile("some_existing_container.bdoc"). 
    build(); 

// SignHelper is a custom helper class for reading a certificate from disk
X509Certificate signingCert = SignHelper.readCertificate("some_signing_certificate.pem");

// Get the data to be signed by the user
DataToSign dataToSign = SignatureBuilder.
    aSignature(container).
    withSigningCertificate(signingCert).
    buildDataToSign();

try {
    // Comment out either container or dataToSign serialization to see that both fail
    byte[] serializedContainer = SerializationUtils.serialize(container);
    byte[] serializedDataToSign = SerializationUtils.serialize(dataToSign);
} catch (SerializationException e) {
    e.printStackTrace();
}

Writing Container directly to OutputStream

Is there any way to write a Container directly to an OutputStream without storing everything in memory/files? Container.save(OutputStream) is a deprecated wrapper for Container.saveAsStream(), which creates and returns a ByteArrayInputStream. That is something we might want to avoid, especially for large containers.

We can of course use Container.saveAsFile(String) (again, why String and no option for File/Path?) to save the contents in a temporary file, then copy it to the OutputStream, but that's a bit tedious IMHO.

Is there a reason Container.save(OutputStream) is deprecated?

Why does the proxy configuration functionality keep getting pushed back?

There's an actual need for using digidoc4j through proxys because of the internal security in companies. However the proxy configuration task in pivotal has been pushed back yet another 3 months. The systems need to be migrated to the new standard bdoc and this is just not possible without modifying the library to the extent where it cannot be updated anymore using this repository.

Use streams when calculating digest of data file

Currently there is an upper limit to the size of signable data files, related to the servers available memory.

The problem is, that in byte[] org.digidoc4j.DataFile.calculateDigestInternal(DigestAlgorithm digestAlgorithm), the digest calculation function uses getBytes - internally, the whole datafile is loaded to memory, which is inefficient.

A more efficient solution would be to use the byte[] eu.europa.esig.dss.digest(final DigestAlgorithm digestAlgo, final InputStream inputStream).
In this case, the digest is calculated over a stream. Internally, they use a 4096 byte buffer.

Attached is a zip of patch of possible fix (generated using git diff on develop branch).
digidoc4j_datafile_streams.zip

Required where:

  • low memory sysems
  • Systems with large files
  • Systems with large numbers of parallel users

Best regards,
Mart Simisker

keystore files included cannot be opened by jdk7

Spent few days setting up digidoc4j on jdk7.
Got always error: keytool error: java.io.IOException: Invalid keystore format

Came out that these files (digidoc4j/digidoc4j/src/main/resources/keystore/*.jks) cannot be opened by jdk7.
Probably they are generated by jdk8.

c:>C:\dev\java\jdk-7u80-windows-x64\bin\keytool -list -keystore C:\dev\git\digidoc4j\digidoc4j\src\main\resources\keystore\keystore.jks -v
keytool error: java.io.IOException: Invalid keystore format
java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at sun.security.tools.KeyTool.doCommands(Unknown Source)
at sun.security.tools.KeyTool.run(Unknown Source)
at sun.security.tools.KeyTool.main(Unknown Source)

c:>C:\dev\java\jdk-8u181-windows-x64\bin\keytool -list -keystore C:\dev\git\digidoc4j\digidoc4j\src\main\resources\keystore\keystore.jks -v
Enter keystore password:

It would be good if project is jdk7 ready "out of the box" as stated in wiki :)

Thank You in advance!

no main manifest attribute

Hi,

I'm new in java and .jar application

I'm download digidoc4j-1.0.7.2.jar, then I double click it and its nothing response.

After I run it by using command java -jar "filePath". I got no main manifest attribute message

Thank you

DataToSign deserialization doesn't work for library releases started from 2.x

Summary
When DataToSign object is de-serialized ConfigurationSingeltonHolder creates new default configuration from YAML file. If system property "digidoc4j.mode" is not set-up than it is "PROD" by default. This leads to corrupted initial container configuration and there is no way to restore container configuration settings that DataToSign was initially created with.

BDocSerializationTest (twoStepSigningWithSerialization()) doesn't show this error due to global variable set-up at AbstractTest: this.setGlobalMode(Configuration.Mode.TEST); It loads default TEST configuration all the time and there is no check of modified configuration parameters.

Impact

  • TEST mode is completely broken if not using global "digidoc4j.mode"
  • customizing Configuration at runtime is not possible

Scope
Latest release and 2.1.0 were tested and both are affected. Probably entire 2.x branch is affected. 1.0.7.2 release is not affected.

Test code

@Test
public void twoStepSigningWithVanillaConf()  throws ClassNotFoundException, Base64DecodingException, ParseException, IOException, CertificateException {
    String signCertificate = " ...... put any X509 PEM encoded cert here......"
    Configuration configuration = new Configuration(Configuration.Mode.TEST);
    configuration.setOcspSource("http://aia.demo.sk.ee/esteid2018");

    Container container = ContainerBuilder
        .aContainer()
        .withConfiguration(configuration)
        .withDataFile(new ByteArrayInputStream("funny_rabbit".getBytes()), "test.txt", "text/plain")
        .build();

    X509Certificate sigCert =
        (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(signCertificate.getBytes()));

    DataToSign dataToSign = SignatureBuilder.aSignature(container)
        .withSigningCertificate(sigCert).buildDataToSign();

    String serialized = serializeObjectToString(dataToSign);
   
    // Here comes configuration reset and new default configuration is created. 
    // Any configuration settings like OCSP source above are lost
    dataToSign = (DataToSign) deserializeObjectFromString(serialized);
    System.out.println(dataToSign.getSignatureParameters().getSignatureId());
  }

 private String serializeObjectToString(Object object) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(object);
    oos.close();
    bos.close();
    byte[] output = bos.toByteArray();
    return Base64.encode(output);
  }

  private Object deserializeObjectFromString(String object)
      throws IOException, ClassNotFoundException, ParseException, Base64DecodingException {
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.decode(object)));
    return ois.readObject();
  }

Debug output (some lines are stripped-out)

06.12.2018 16:11:15.843 DEBUG [main] [org.digidoc4j.Configuration.<init>:216] - ------------------------ <MODE: TEST> ------------------------
06.12.2018 16:11:15.860 DEBUG [main] [org.digidoc4j.Configuration.loadConfiguration:336] - Loading configuration from file <digidoc4j.yaml>
06.12.2018 16:11:15.861 DEBUG [main] [org.digidoc4j.Configuration.loadConfiguration:342] - Configuration file <digidoc4j.yaml> not found. Trying to search from jar file
06.12.2018 16:11:15.987 DEBUG [main] [org.digidoc4j.Configuration.mapToJDigiDocConfiguration:1399] - loading JDigiDoc configuration
06.12.2018 16:11:15.987 DEBUG [main] [org.digidoc4j.Configuration.loadInitialConfigurationValues:1174] - ------------------------ LOADING INITIAL CONFIGURATION ------------------------
06.12.2018 16:11:15.987 DEBUG [main] [org.digidoc4j.Configuration.defaultIfNull:1277] - Parameter: DIGIDOC_SECURITY_PROVIDER
06.12.2018 16:11:15.988 DEBUG [main] [org.digidoc4j.Configuration.defaultIfNull:1277] - Parameter: DIGIDOC_SECURITY_PROVIDER_NAME
...
...
06.12.2018 16:11:15.998 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TspsCount> to <0>
06.12.2018 16:11:15.998 DEBUG [main] [org.digidoc4j.Configuration.getConfigurationParameter:1561] - Requested parameter <AllowASN1UnsafeInteger> not found
06.12.2018 16:11:15.998 DEBUG [main] [org.digidoc4j.Configuration.initDefaultValues:1131] - ------------------------ DEFAULTS ------------------------
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <ConnectionTimeoutInMillis> to <1000>
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SocketTimeoutInMillis> to <1000>
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslKeyStorePassword> to <digidoc4j-password>
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <RevocationAndTimestampDeltaInMinutes> to <1440>
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslCacheExpirationTimeInMillis> to <86400000>
06.12.2018 16:11:16.001 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <AllowedTimestampAndOCSPResponseDeltaInMinutes> to <15>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SignatureProfile> to <LT>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SignatureDigestAlgorithm> to <SHA256>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <IsFullSimpleReportNeeded> to <false>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TspSource> to <http://demo.sk.ee/tsa>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslLocation> to <https://open-eid.github.io/test-TL/tl-mp-test-EE.xml>
06.12.2018 16:11:16.002 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslKeyStoreLocation> to <keystore/test-keystore.jks>
...
...
06.12.2018 16:11:16.008 DEBUG [main] [org.digidoc4j.Configuration.getConfigurationParameter:1561] - Requested parameter <AllowASN1UnsafeInteger> not found
06.12.2018 16:11:16.008 DEBUG [main] [org.digidoc4j.Configuration.<init>:220] - ------------------------ </MODE: TEST> ------------------------
06.12.2018 16:11:16.009 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <OcspSource> to <http://aia.demo.sk.ee/esteid2018>
...
...
06.12.2018 16:11:17.138 DEBUG [main] [o.d.i.a.xades.XadesSigningDssFacade.getDataToSign:92] - Got data to sign from DSS
06.12.2018 16:11:17.139 DEBUG [main] [org.digidoc4j.SignatureParameters.setSignatureId:122] - Set signature id to id-d3a6673547a8c679879c4b4ddd1904b5
....... Here comes deserialization....
06.12.2018 16:14:49.144 DEBUG [main] [org.digidoc4j.ConfigurationRegistry.readObject:68] - Seal <a9884f8a698b315d45b1d326057b4f0f> found
06.12.2018 16:14:49.145 INFO  [main] [o.d.i.ConfigurationSingeltonHolder.getInstance:33] - Creating a new configuration instance
06.12.2018 16:14:49.146 DEBUG [main] [org.digidoc4j.Configuration.<init>:216] - ------------------------ <MODE: PROD> ------------------------
06.12.2018 16:14:49.146 DEBUG [main] [org.digidoc4j.Configuration.loadConfiguration:336] - Loading configuration from file <digidoc4j.yaml>
06.12.2018 16:14:49.147 DEBUG [main] [org.digidoc4j.Configuration.loadConfiguration:342] - Configuration file <digidoc4j.yaml> not found. Trying to search from jar file
06.12.2018 16:14:49.290 DEBUG [main] [org.digidoc4j.Configuration.mapToJDigiDocConfiguration:1399] - loading JDigiDoc configuration
06.12.2018 16:14:49.290 DEBUG [main] [org.digidoc4j.Configuration.loadInitialConfigurationValues:1174] - ------------------------ LOADING INITIAL CONFIGURATION ------------------------
06.12.2018 16:14:49.290 DEBUG [main] [org.digidoc4j.Configuration.defaultIfNull:1277] - Parameter: DIGIDOC_SECURITY_PROVIDER
06.12.2018 16:14:49.291 DEBUG [main] [org.digidoc4j.Configuration.defaultIfNull:1277] - Parameter: DIGIDOC_SECURITY_PROVIDER_NAME
...
...
06.12.2018 16:14:49.301 DEBUG [main] [org.digidoc4j.Configuration.getConfigurationParameter:1561] - Requested parameter <AllowASN1UnsafeInteger> not found
06.12.2018 16:14:49.302 DEBUG [main] [org.digidoc4j.Configuration.initDefaultValues:1131] - ------------------------ DEFAULTS ------------------------
06.12.2018 16:14:49.302 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <ConnectionTimeoutInMillis> to <1000>
06.12.2018 16:14:49.303 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SocketTimeoutInMillis> to <1000>
06.12.2018 16:14:49.303 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslKeyStorePassword> to <digidoc4j-password>
06.12.2018 16:14:49.304 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <RevocationAndTimestampDeltaInMinutes> to <1440>
06.12.2018 16:14:49.304 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslCacheExpirationTimeInMillis> to <86400000>
06.12.2018 16:14:49.304 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <AllowedTimestampAndOCSPResponseDeltaInMinutes> to <15>
06.12.2018 16:14:49.305 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SignatureProfile> to <LT>
06.12.2018 16:14:49.305 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <SignatureDigestAlgorithm> to <SHA256>
06.12.2018 16:14:49.305 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <IsFullSimpleReportNeeded> to <false>
06.12.2018 16:14:49.306 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TspSource> to <http://tsa.sk.ee>
06.12.2018 16:14:49.306 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslLocation> to <https://ec.europa.eu/information_society/policy/esignature/trusted-list/tl-mp.xml>
06.12.2018 16:14:49.306 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TslKeyStoreLocation> to <keystore/keystore.jks>
06.12.2018 16:14:49.307 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <ValidationPolicy> to <conf/constraint.xml>
06.12.2018 16:14:49.307 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <OcspSource> to <http://ocsp.sk.ee/>
...
...
06.12.2018 16:14:49.321 DEBUG [main] [org.digidoc4j.Configuration.setConfigurationParameter:1540] - Setting parameter <TspsCount> to <0>
06.12.2018 16:14:49.322 DEBUG [main] [org.digidoc4j.Configuration.getConfigurationParameter:1561] - Requested parameter <AllowASN1UnsafeInteger> not found
06.12.2018 16:14:49.322 DEBUG [main] [org.digidoc4j.Configuration.<init>:220] - ------------------------ </MODE: PROD> ------------------------
06.12.2018 16:14:49.326 DEBUG [main] [org.digidoc4j.ConfigurationRegistry.checkCurrentConfiguration:86] - Seal a9884f8a698b315d45b1d326057b4f0f != 72dfc42a1a123e5e8cbeeb5a8edae4e4
06.12.2018 16:14:49.327 INFO  [main] [org.digidoc4j.ConfigurationRegistry.checkCurrentConfiguration:89] - Overwriting deserialized registry with current one

There is no AIA extension for certificate download.

Hello,
I'm trying to implement it using brazilian certificate, but when I'm testing it the error below is shown

e.e.esig.dss.tsl.service.TSLRepository   : Nb of loaded trusted lists : 23
e.e.esig.dss.tsl.service.TSLRepository   : Nb of trusted certificates : 1089
e.e.esig.dss.tsl.service.TSLRepository   : Nb of skipped trusted lists : 2
e.e.esig.dss.tsl.service.TSLRepository   : http://crc.bg/files/_bg/TSL-CRC-BG-signed.xml is skipped
e.e.esig.dss.tsl.service.TSLRepository   : https://www.nccert.pl/tsl/PL_TSL.xml is skipped
e.e.e.d.v.SignatureValidationContext     : Retrieving A39E3A90B8F527913382C78F0B306AFF914B42C1F69DE53F65B81E930DF4A1E5 certificate's issuer using AIA.
e.e.e.d.v.SignatureValidationContext     : An error occured while HTTP GET for url 'http://icp-brasil.acfenacon.com.br/repositorio/certificados/AC_Instituto_Fenacon_RFBG2.p7c' : Tempo esgotado para conexรฃo (Connection timed out)
e.e.e.d.v.SignatureValidationContext     : Retrieving 1E49F497D89D430AAD534B622D82BD9B9D0D4AFDB7B7D36986C5DF0981D9067D certificate's issuer using AIA.
eu.europa.esig.dss.DSSUtils              : There is no AIA extension for certificate download.
e.e.e.d.v.SignatureValidationContext     : The issuer certificate cannot be loaded using AIA.
e.e.e.d.v.CommonCertificateVerifier      : + New CommonCertificateVerifier created.
o.d.impl.bdoc.BDocSignatureBuilder       : Signature does not contain OCSP response
e.s.h.demo.controller.SigningController  : Error Signing document

org.digidoc4j.exceptions.OCSPRequestFailedException: OCSP request failed
	at org.digidoc4j.impl.bdoc.BDocSignatureBuilder.validateOcspResponse(BDocSignatureBuilder.java:167) ~[digidoc4j-1.0.4.jar:1.0.4]
	at org.digidoc4j.impl.bdoc.BDocSignatureBuilder.createSignature(BDocSignatureBuilder.java:102) ~[digidoc4j-1.0.4.jar:1.0.4]
	at org.digidoc4j.impl.bdoc.BDocSignatureBuilder.finalizeSignature(BDocSignatureBuilder.java:91) ~[digidoc4j-1.0.4.jar:1.0.4]
	at org.digidoc4j.DataToSign.finalize(DataToSign.java:79) ~[digidoc4j-1.0.4.jar:1.0.4]
	at ee.sk.hwcrypto.demo.signature.FileSigner.signContainer(FileSigner.java:73) ~[classes/:na]
	at ee.sk.hwcrypto.demo.controller.SigningController.createContainer(SigningController.java:98) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) [spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: The current request is not a multipart request] with root cause

org.springframework.web.multipart.MultipartException: The current request is not a multipart request
	at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.assertIsMultipartRequest(RequestParamMethodArgumentResolver.java:216) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:167) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:90) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]

PKCS11SignerTestMain does not work

Hi.

I have tried to use prototype.PKCS11SignerTestMain class, which is available in the digidoc4j project, and it does not work at the moment. I have used my own real Estonian ID card (new generation, received in February 2016) and my own PIN2, but the class throws an exception when validating signature:

Exception in thread "main" eu.europa.esig.dss.DSSException: Cryptographic signature verification has failed / Signature length not correct: got 0 but was expecting 256
at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineLT.checkSignatureIntegrity(XAdESLevelBaselineLT.java:104)
at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineLT.extendSignatureTag(XAdESLevelBaselineLT.java:75)
at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:140)
at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:73)
at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:95)
at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:45)
at org.digidoc4j.impl.bdoc.xades.XadesSigningDssFacade.signDocument(XadesSigningDssFacade.java:77)
at org.digidoc4j.impl.bdoc.BDocSignatureBuilder.finalizeSignature(BDocSignatureBuilder.java:82)
at org.digidoc4j.impl.bdoc.BDocSignatureBuilder.invokeSigningProcess(BDocSignatureBuilder.java:66)
at org.digidoc4j.SignatureBuilder.invokeSigning(SignatureBuilder.java:106)
at prototype.PKCS11SignerTestMain.signWithIDCard(PKCS11SignerTestMain.java:32)
at prototype.PKCS11SignerTestMain.main(PKCS11SignerTestMain.java:39)

Is this a known issue? Would appreciate any feedback as to how to make it work.

Full log can be found in the attached archive.
PKCS11SignerTestMain.zip

(DigiDoc4j, DSS) TLWellSigned parameter not working

TLWellSigned is parameter between eIDAS tags in DSS constraint.xml.
Reason: DiagnosticDataBuilder class only accepts TrustedListsCertificateSource implementation of CertificateSource interface, but DigiDoc4 has its own implementation called ClonedTslCertificateSource.

public DiagnosticDataBuilder trustedListsCertificateSource(CertificateSource trustedCertSource) { if (trustedCertSource instanceof TrustedListsCertificateSource) { this.trustedListCertSource = (TrustedListsCertificateSource) trustedCertSource; } return this; }

PKCS12 signature with B_BES profile is missing SignaturePolicyIdentifier tag in signature*.xml

Hi!

We are signing a BDOC container with PKCS12 token and then sending it to the Swedbank Gateway web service. However, all the files come back with an error. Discussing with the IT department in Swedbank they came up with a reason - missing SignaturePolicyIdentifier tag in the signature*.xml. I rechecked to see if this was correct and indeed the signatures created with ID-card all have the SignaturePolicyIdentifier tag in them while the PKCS12 B_BES signature doesn't have it. Is it something that should be missing in the case of B_BES signatures? Can we add this information to the signature manually by editing the following SignatureBuilder code? I didn't find an API way of doing this though.

This is the code we are using for the signing process:

sigToken = new PKCS12SignatureToken(privateKey, password);
Signature sig = SignatureBuilder.aSignature(container)
            .withSignatureProfile(SignatureProfile.B_BES)
            .withRoles("ERP")
            .withSignatureToken(sigToken)
            .invokeSigning();
container.addSignature(sig);
container.saveAsFile(containerPath);

Helper.deleteTmpFiles() is not thread-safe

Helper.deleteTmpFiles() deletes all "digidoc4j*.tmp" files not taking into account which files were actually created by the current process. If there are other concurrent digidoc4j processes using temporary files (ie all StreamDocuments), they fail with FileNotFoundExceptions.

Possible solutions:

  1. As deleteOnExit() seems to be called on all temporary files anyway, one possibility is to remove the deleteTmpFiles() method call (or replace the delete() with deleteOnExit()) and live with the fact they are deleted after shutdowns
  2. Delete only the temporary files created by the current process
  3. Introducing a configurable delay before file deletion would also work

NullPointerException when getting ocsp certificate from signature

I am trying to get ocsp certificate from signature and digidoc4j throws NullPointerException.

container used for testing:
testing.zip

example code:
//container from existing file
Container container = ContainerBuilder.
aContainer().
fromExistingFile("testing.asice").build();
//signature from container
Signature signature = container.getSignatures().get(0);
//trying to get certificate and DD4J throws NullPointerException
X509Cert cert = signature.getOCSPCertificate();

error message in console:
Exception in thread "main" java.lang.NullPointerException
at org.digidoc4j.impl.bdoc.xades.TimemarkSignature.getCN(TimemarkSignature.java:125)
at org.digidoc4j.impl.bdoc.xades.TimemarkSignature.getOCSPCommonName(TimemarkSignature.java:119)
at org.digidoc4j.impl.bdoc.xades.TimemarkSignature.findOcspCertificate(TimemarkSignature.java:106)
at org.digidoc4j.impl.bdoc.xades.TimemarkSignature.getOCSPCertificate(TimemarkSignature.java:56)
at org.digidoc4j.impl.bdoc.BDocSignature.getOCSPCertificate(BDocSignature.java:80)

org.digidoc4j.X509Cert.loadSubjectNameParts method broken

When trying to read all the fields from Subject of an X509 certificate, I'm getting ArrayIndexOutOfBoundsException on line 277 I guess because of the way the CN field is constructed (includes commas). All the parts up until the givenname part of the CN can be read correctly.

This line gives the error:
container.getSignatures().get(0).getSigningCertificate().getSubjectName(SubjectName.SERIALNUMBER)

Error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.digidoc4j.X509Cert.loadSubjectNameParts(X509Cert.java:277)
at org.digidoc4j.X509Cert.getSubjectName(X509Cert.java:263)

Remove static reference to logger implementation

snippet from DDocOpener:
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);

This creates mandatory dependency to use logback classic as implementation for the slf4j api. Not all applications using digidoc4j are using logback implementation, which prevents from applications to upgrade to latest versions of digidoc4j. All such occurrences must be removed. The usage should be replaced with Logger logger = LoggerFactory.getLogger(DDocOpener.class); that you have in the beginning of the class.

Different behavior between AsicFileContainerParser and AsicStreamContainerParser

Only AsicStreamContainerParser class uses updateDataFilesMimeType method and therefore validating this container may get a different result compares to AsicFileContainerParser.
DSS MimeType class can throw an exception if mimeType does not match the regex
"([\\w])*/([\\w\\-\\+\\.])*"
Exception:

eu.europa.esig.dss.DSSException: 'txt.html' is not conformant mime-type string!
	at eu.europa.esig.dss.MimeType.<init>(MimeType.java:98) ~[dss-model-5.0.d4j.5.jar:na]
	at eu.europa.esig.dss.MimeType.fromMimeTypeString(MimeType.java:215) ~[dss-model-5.0.d4j.5.jar:na]
	at org.digidoc4j.DataFile.getMimeType(DataFile.java:107) ~[digidoc4j-1.0.7.2.jar:na]
	... 100 common frames omitted

Unable to open bdoc container signed with digidoc4j 1.0.2

We're experiencing problems when using digidoc4j version 1.0.2 in our web application

Use case:

User wants to add his / her signature to the existing bdoc container.

Relevant code parts:

     //prepare the data to sign.
     String certHex = this.currentInputData.getGlobalData().get("param");
    byte[] certBytes = AllkiriUtil.hex2bin(certHex);
    certificate = AllkiriUtil.readCertificate(certBytes);
    dataToSign = SignatureBuilder
            .aSignature(container)
            .withSigningCertificate(certificate)
            .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256)
            .buildDataToSign();
    byte[] digest = dataToSign.getDigestToSign();
    JsonObject response = new JsonObject(); 
    response.setStringProperty("digest", AllkiriUtil.bin2hex(digest));              
    ((HttpOutputData)getOutputData()).getWriter().write(response.toString());

After the signature is sent back from the client we finalize it like this:

        Signature signature = dataToSign.finalize(signatureBytes);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        container.addSignature(signature);
        container.save(stream);
        //save to file, send it back to client

Expected behaviour:

User is able to open up signed container using latest version of digidoc client application.

Actual behaviour:

Everything works as expected If the bdoc container is signed with an older version of the certificate ESTEID_SK 2011

If user tries to sign the container with ESTEID_SK 2015, digidoc client does not open the signed container with the following error message:

BDoc.cpp:452 Failed to parse signature 'META-INF/signatures0.xml'.
SignatureBES.cpp:300 Failed to parse signature XML: :1:9905 error: ID value 'id-a1abfebaade6da7004edd61fd77cde27-RESPONDER_CERT' is not unique

container is attached to the issue report:
Liitumise_taotlus_75010430.bdoc.zip

NO_CERTIFICATE_CHAIN_FOUND when creating a BDOC container

Hi.

I am experimenting with the final release of DigiDoc4j library (version 1.0.0). I have generated an access certificate (.p12d file) thru https://www.sk.ee/getaccess/?lang=eng using my own Estonian ID card, and I use this file in a simple program that just creates a BDOC container and saves it to a local file system. Although the container is created successfully the signature is marked "Not valid" and I see some validation errors in the logs.

What is interesting is that after creating a signature and validating it (signature.validate()), I get NO validation errors. But when validating a resulting BDOC container (container.validate()) , there are some errors. Below I will provide the simplified code and some logs to illustrate this issue.


Main.java

Container container = ContainerBuilder.
        aContainer(ContainerBuilder.BDOC_CONTAINER_TYPE).
        withDataFile("src/main/resources/test.txt", "text/plain").
        build();

String privateKeyPath = "src/main/resources/905281.p12d";
char[] password = "password".toCharArray();
PKCS12SignatureToken signatureToken = new PKCS12SignatureToken(privateKeyPath, password);   

Signature signature = SignatureBuilder.
        aSignature(container).
        withSignatureDigestAlgorithm(DigestAlgorithm.SHA256).
        withSignatureProfile(SignatureProfile.LT).
        withCountry("Estonia").
        withStateOrProvince("Harjumaa").
        withCity("Tallinn").
        withPostalCode("12618").
        withSignatureToken(signatureToken).
        invokeSigning();

List<DigiDoc4JException> validationExceptions = signature.validate();
if (validationExceptions != null && validationExceptions.size() > 0) {
    System.err.println("***** Signature validation failed:");
    for (DigiDoc4JException e : validationExceptions) {
        System.err.println(e.getMessage());
    }

    return;
} else {
    System.out.println("***** Signature validation was successful!");
}

container.addSignature(signature);

container.saveAsFile("result.bdoc");

ValidationResult validationResult = container.validate();
if (validationResult.isValid()) {
    System.out.println("***** Container validation was successful!");
} else {
    System.err.println("***** There were errors/warnings when validating the container.");

    List<DigiDoc4JException> containerErrors = validationResult.getContainerErrors();
    if (containerErrors != null && containerErrors.size() > 0) {
        System.err.println("Errors:");
        for (DigiDoc4JException e : validationResult.getContainerErrors()) {
            System.err.println(e.getMessage());
        }
    }

    List<DigiDoc4JException> warnings = validationResult.getWarnings();
    if (warnings != null && warnings.size() > 0) {
        System.err.println("\nWarnings:");
        for (DigiDoc4JException e : validationResult.getWarnings()) {
            System.err.println(e.getMessage());
        }
    }

}

System.out.println("\n***** Validation report *****");
System.out.println(validationResult.getReport());

Logs:

14:13:31.569 [main] INFO org.digidoc4j.Configuration - Loading configuration from file digidoc4j.yaml
14:13:31.585 [main] INFO org.digidoc4j.Configuration - Configuration file digidoc4j.yaml not found. Trying to search from jar file.
14:13:31.616 [main] INFO org.digidoc4j.Configuration - Configuration loaded for PROD mode
14:13:31.668 [main] INFO eu.europa.ec.markt.dss.validation102853.CommonCertificateVerifier - + New CommonCertificateVerifier created.
14:13:31.748 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - New BDoc container created
14:13:31.748 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Adding data file: src/main/resources/test.txt, mime type: text/plain
14:13:31.770 [main] INFO org.digidoc4j.signers.PKCS12SignatureToken - Using PKCS#12 signature token from file: src/main/resources/905281.p12d
14:13:31.867 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Signing BDoc container
14:13:31.867 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Getting data to sign
14:13:31.917 [main] INFO org.digidoc4j.signers.PKCS12SignatureToken - Signing with PKCS#12 signature token, using digest algorithm: SHA256
14:13:31.917 [main] INFO eu.europa.ec.markt.dss.signature.token.AbstractSignatureTokenConnection - Signature algorithm: RSA/SHA256
14:13:31.967 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Finalizing BDoc signature
14:13:32.988 [main] WARN eu.europa.ec.markt.dss.validation102853.tsl.AbstractTrustService - java.lang.IllegalArgumentException: improperly specified input name: serialNumber=896929130327, givenName=OCSP, SN=Responder 03-1, CN=OCSP Responder 03-1, C=AT
14:13:34.603 [main] WARN eu.europa.ec.markt.dss.validation102853.tsl.AbstractTrustService - Unsupported algorithm: 1.2.840.113549.1.1.10
14:13:35.172 [main] WARN eu.europa.ec.markt.dss.validation102853.tsl.TrustedListsCertificateSource - Other problem: eu.europa.ec.markt.dss.exception.DSSException: Not ETSI compliant signature. The signature is not valid.
14:13:37.670 [main] WARN eu.europa.ec.markt.dss.validation102853.tsl.TrustedListsCertificateSource - Other problem: eu.europa.ec.markt.dss.exception.DSSException: Not ETSI compliant signature. The signature is not valid.
14:13:38.564 [main] INFO eu.europa.ec.markt.dss.signature.xades.XAdESLevelBaselineT - ====> Extending: IN MEMORY DOCUMENT
14:13:38.652 [main] INFO eu.europa.ec.markt.dss.validation102853.tsp.OnlineTSPSource - Status: Operation Okay
14:13:38.652 [main] INFO eu.europa.ec.markt.dss.validation102853.tsp.OnlineTSPSource - SID: org.bouncycastle.cms.SignerId@4e0148f2
14:13:38.752 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - Retrieving 49c707cdd2dfbf683ab71a457aea4caf0cefd20c9088972950e853d49787b680 certificate's issuer using AIA.
14:13:38.752 [main] INFO eu.europa.ec.markt.dss.DSSUtils - There is no AIA extension for certificate download.
14:13:38.752 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - The issuer certificate cannot be loaded using AIA.
14:13:38.765 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - Retrieving 1e49f497d89d430aad534b622d82bd9b9d0d4afdb7b7d36986c5df0981d9067d certificate's issuer using AIA.
14:13:38.765 [main] INFO eu.europa.ec.markt.dss.DSSUtils - There is no AIA extension for certificate download.
14:13:38.765 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - The issuer certificate cannot be loaded using AIA.
14:13:38.921 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - Retrieving 49c707cdd2dfbf683ab71a457aea4caf0cefd20c9088972950e853d49787b680 certificate's issuer using AIA.
14:13:38.921 [main] INFO eu.europa.ec.markt.dss.DSSUtils - There is no AIA extension for certificate download.
14:13:38.921 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - The issuer certificate cannot be loaded using AIA.
14:13:38.999 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Signing BDoc successfully completed
14:13:38.999 [main] INFO org.digidoc4j.impl.bdoc.BDocSignature - Signature has 0 validation errors

***** Signature validation was successful!
14:13:38.999 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Saving container to file: result.bdoc
14:13:39.000 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - Verifying BDoc container
14:13:39.181 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - Retrieving 49c707cdd2dfbf683ab71a457aea4caf0cefd20c9088972950e853d49787b680 certificate's issuer using AIA.
14:13:39.181 [main] INFO eu.europa.ec.markt.dss.DSSUtils - There is no AIA extension for certificate download.
14:13:39.182 [main] INFO eu.europa.ec.markt.dss.validation102853.SignatureValidationContext - The issuer certificate cannot be loaded using AIA.
14:13:39.220 [main] ERROR org.digidoc4j.impl.bdoc.XadesSignatureValidator - The certificate chain is not trusted, there is no trusted anchor.
14:13:39.227 [main] INFO org.digidoc4j.impl.bdoc.ManifestValidator - Validation of meta data within the manifest file and signature files error count: 0
14:13:39.228 [main] INFO org.digidoc4j.impl.bdoc.BDocSignature - Signature has 1 validation errors
14:13:39.229 [main] INFO org.digidoc4j.impl.bdoc.AsicFacade - BDoc container is valid: false

***** There were errors/warnings when validating the container.

***** Validation report *****

<?xml version="1.0" encoding="UTF-8"?><ValidationReport><SignatureValidation ID="S0">
  <Policy>
      <PolicyName>QES AdESQC TL based</PolicyName>
      <PolicyDescription>RIA customized validation policy</PolicyDescription>
  </Policy>
  <ValidationTime>2016-01-12T14:13:39Z</ValidationTime>
  <DocumentName/>
  <Signature Id="S0" SignatureFormat="XAdES_BASELINE_LT">
      <SigningTime>2016-01-12T12:13:31Z</SigningTime>
      <SignedBy>LEVAN_KEKELIDZE</SignedBy>
      <Indication>INDETERMINATE</Indication>
      <SubIndication>NO_CERTIFICATE_CHAIN_FOUND</SubIndication>
      <Error NameId="BBB_XCV_CCCBB_ANS">The certificate chain is not trusted, there is no trusted anchor.</Error>
      <SignatureLevel>AdES</SignatureLevel>
      <SignatureScopes>
          <SignatureScope name="test.txt" scope="FullSignatureScope">Full document</SignatureScope>
      </SignatureScopes>
  <AdditionalValidation Error="0"><Description>The certificate chain is not trusted, there is no trusted anchor.</Description></AdditionalValidation></Signature>
  <ValidSignaturesCount>0</ValidSignaturesCount>
  <SignaturesCount>1</SignaturesCount>
</SignatureValidation><ManifestValidation/></ValidationReport>

Technical information regarding signature from a DigiDoc client application:

SignatureA.cpp:160 Signature validation
SignatureBES.cpp:762 Unable to verify signing certificate
SignatureBES.cpp:752 Signing certificate does not contain NonRepudiation key usage flag
SignatureTM.cpp:160 RevocationValues object is missing
SignatureTM.cpp:142 Signature validation
SignatureBES.cpp:762 Unable to verify signing certificate
SignatureBES.cpp:752 Signing certificate does not contain NonRepudiation key usage flag
SignatureTM.cpp:160 RevocationValues object is missing
OCSP.cpp:113 Response is empty

Another issue is that when in the above code I use a "time mark" signature profile SignatureBuilder.aSignature(container).withSignatureProfile(SignatureProfile.LT_TM) besides the above errors in the logs I cannot open a newly created container at all: insted I get the following errors form DigiDoc client application:

An error occurred while opening the document.

BDoc.cpp:450 Failed to parse signature 'META-INF/signatures0.xml'.
SignatureBES.cpp:294 Failed to parse signature XML: :1:4488 error: element 'UnsignedSignatureProperties' is not allowed for content model
'(CounterSignature|SignatureTimeStamp|CompleteCertificateRefs|CompleteRevocationRefs|AttributeCertificateRefs|AttributeRevocationRefs|
SigAndRefsTimeStamp|RefsOnlyTimeStamp|CertificateValues|RevocationValues|AttrAuthoritiesCertValues|AttributeRevocationValues|ArchiveTimeStamp|)'



Maybe I am doing something wrong or there is something wrong with the generated .p12d file. Anyways would appreciate any help with resolving this issue.

Default TEST configuration TSL location url not working

Sometime last week we could no longer create signatures in TEST mode. We got the following error org.digidoc4j.exceptions.TslCertificateSourceInitializationException: Unable to load the LOTL: content is empty at org.digidoc4j.impl.bdoc.tsl.LazyTslCertificateSource.refreshTsl(LazyTslCertificateSource.java:139) at org.digidoc4j.impl.bdoc.tsl.LazyTslCertificateSource.initTsl(LazyTslCertificateSource.java:124) at org.digidoc4j.impl.bdoc.tsl.LazyTslCertificateSource.refreshIfCacheExpired(LazyTslCertificateSource.java:102) at org.digidoc4j.impl.bdoc.tsl.ClonedTslCertificateSource.initializeClonedTsl(ClonedTslCertificateSource.java:51)

It seems that the url (https://demo.sk.ee/TSL/tl-mp-test-EE.xml) specified in the default configuration is no longer responding. Is this something which we now have to manually configure?

DataToSign.getDigestToSign() was removed

In version 1.0.7.2, it was possible to calculate hash of container using following code:

DataToSign dataToSign = SignatureBuilder
        .aSignature(container)
        .withEncryptionAlgorithm(encryptionAlgorithm)
        .withSignatureProfile(SignatureProfile.LT) // asic-e
        .withSigningCertificate(signingCert)
        .withSignatureDigestAlgorithm(DigestAlgorithm.SHA256)
        .buildDataToSign();

//Data to sign contains the digest that should be signed
byte[] digestToSign = dataToSign.getDigestToSign();

Calculated hash can then be used for singing using idcard (hwcrypto.sign), Mobile-ID (MobileSignHash) or Smart-ID (/signature/document/:documentnumber).

It appears, that in 1.0.8.beta.1 following change was made:

  • method DataToSign.getDigestToSign() is renamed to DataToSign.getDataToSign().

But what getDataToSign() returns since 1.0.8.beta.1 is not hash.

The question is what is now (since 1.0.8.beta.1) the best method to get hash of container, which then could be used for signing?

container.getType() returning wrong container type

I created an ASICS container but when I try to load the container in another project, it returns continer type as BDOC. My creation and check code is below:
Container container = ContainerBuilder. aContainer(Container.DocumentType.ASICS). withConfiguration(config). withDataFile("sample_transaction/contract.txt", "text/plain"). build();
and
Container container1 = ContainerBuilder.aContainer().fromExistingFile("ContractASIC").build();
return BDOC.

I know BDOC is similar to ASICE and ASICS, but I want it to give me the original type and not a similar type

ExecutorService usage issues prevent clean shutdown

PROBLEM 1: Tomcat web application. After validating 1 bdoc, tomcat fails to do a clean shutdown because there are two non-daemon threads running forever:

"pool-5-thread-1" #78 prio=5 os_prio=0 tid=0x00007f3346b55800 nid=0x77c7 waiting on condition [0x00007f3304ff2000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c5c6d1c8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"pool-5-thread-2" #79 prio=5 os_prio=0 tid=0x00007f3346c17000 nid=0x77c8 waiting on condition [0x00007f3304ef1000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c5c6d1c8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

CAUSE: Container.validate() ends up in BDocContainerValidator.startSignatureValidationInParallel(...), this calls threadPoolManager.submit(validationExecutor), this calls ThreadPoolManager.initializeDefaultThreadExecutor() (because configuration didn't have a threadExecutor instance), and now the ThreadPoolManager contains a default-named (very hard to debug!) fixed thread pool with 2 (because my machine has 2 cores) non-daemon threads, which don't ever shut down - they require an implicit defaultThreadExecutor.shutdown() call for that.

WORKAROUND: I'm setting my own threadExecutor instance into Configuration, so that ThreadPoolManager wouldn't create it's own.

SOLUTION: Either implement shutdown api/hook/logic/documentation or use "short lived" cached thread pool or something else.


PROBLEM 2: https://www.pivotaltracker.com/story/show/128498307

CAUSE: DSS library TSLValidationJob contains an Executors.newCachedThreadPool() with 60 seconds idle timeout. This means that after TSL validation, it takes 60 seconds for this executor service threads to "die". I assume that this is the causes for that bug. TSLValidationJob needs to either provide a hook for shutdown or allow getting/setting your own executorService or something else.

digidoc4j-util is broken after removing xalan module from pom.xml

In commit 1abca62 (at 6.11.2018 10:49) pom.xml was modified and dependencies to xalan module removed. But DSS uses this module and signing use case with digidoc4j-util gets now following exception:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xml/utils/URI$MalformedURIException at eu.europa.esig.dss.xades.validation.XAdESSignature.checkSignatureIntegrity(XAdESSignature.java:1303) at eu.europa.esig.dss.validation.DefaultAdvancedSignature.getSignatureCryptographicVerification(DefaultAdvancedSignature.java:327) at eu.europa.esig.dss.xades.signature.ExtensionBuilder.assertSignatureValid(ExtensionBuilder.java:144) at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatureTag(XAdESLevelBaselineT.java:171) at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineLT.extendSignatureTag(XAdESLevelBaselineLT.java:66) at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:145) at eu.europa.esig.dss.xades.signature.XAdESLevelBaselineT.extendSignatures(XAdESLevelBaselineT.java:78) at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:129) at eu.europa.esig.dss.xades.signature.XAdESService.signDocument(XAdESService.java:151) at org.digidoc4j.impl.asic.xades.XadesSigningDssFacade.signDocument(XadesSigningDssFacade.java:119) at org.digidoc4j.impl.asic.AsicSignatureBuilder.finalizeSignature(AsicSignatureBuilder.java:119) at org.digidoc4j.impl.asic.AsicSignatureBuilder.invokeSigningProcess(AsicSignatureBuilder.java:81) at org.digidoc4j.SignatureBuilder.invokeSigning(SignatureBuilder.java:167) at org.digidoc4j.main.CommandLineExecutor.invokeSigning(CommandLineExecutor.java:483) at org.digidoc4j.main.CommandLineExecutor.signWithPkcs11(CommandLineExecutor.java:476) at org.digidoc4j.main.CommandLineExecutor.signContainer(CommandLineExecutor.java:413) at org.digidoc4j.main.CommandLineExecutor.processContainer(CommandLineExecutor.java:82) at org.digidoc4j.main.DigiDoc4J.execute(DigiDoc4J.java:132) at org.digidoc4j.main.DigiDoc4J.run(DigiDoc4J.java:103) at org.digidoc4j.main.DigiDoc4J.main(DigiDoc4J.java:51)

Caused by: java.lang.ClassNotFoundException: org.apache.xml.utils.URI$MalformedURIException at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 20 more

Please put those modules back :)

Signature is invalid when created with StateOrProvince or more than one Role

Disclaimer
I have not deeply researched the cause of the following errors, so I am not absolutely sure whether those bugs are in the DigiDoc4j library code or in the libdigidocpp library code. But because I am using DigiDoc4j in the first place I'm reporting them here


I am signing documents using external signing scenario (with the help of hwcrypto.js). All goes fine until I create signature with the following meta-data:

1) StateOrProvince (found by Kertu Hiire from RIA)

So if this info is added to the signature the signing process completes successfully ("Signing BDoc successfully completed") and BDOC container is also successfully saved to a file. But when opening this container with DigiDoc3 klient (version 3.12.1.1450 - latest version as of now) it cannot be opened and the following error is shown:

BDoc.cpp:456 Failed to parse signature 'META-INF/signatures0.xml'.
SignatureBES.cpp:300 Failed to parse signature XML: :1:4124 error: element 'StateOrProvince' is not allowed for content model '(City?,StateOrProvince?,PostalCode?,CountryName?)'

digidoc3_error_message1

2) Roles

When adding more that one role to a signature, again all is fine on the DigiDoc4j side: both signing and saving a container to a file. But when opening the container with DigiDoc3 client, although it still can be opened (unlike the previous case) it is shown that the signature is not valid:
digidoc3_error_issue2_1
digidoc3_error_issue2_2
digidoc3_error_issue2_3


Other thoughts

And as you may see in BOTH issue 1 and 2 error messages it is the code in the SignatureBES.cpp file that is responsible for generating those errors. For instance, the restriction (only one role) is enforced ONLY for BDoc-BES format as is seen the code inside the SignatureBES.cpp file.

But important part is that I am explicitly using either Time-mark (SignatureProfile.LT_TM) or Time-stamp (SignatureProfile.TS) so why not SignatureTS.cpp or SignatureTM.cpp are used when opening containers created with the related profiles?

In other words I am not quite sure what is the reason for those errors, i.e. was BDOC container constructed incorrectly or DiciDoc3 client does something wrong.


Here is a code excerpt that shows how I create DataToSign object that is to be externally signed:

DataToSign dataToSign = SignatureBuilder.
                aSignature(container).
                withSigningCertificate(signingCert).
                withSignatureDigestAlgorithm(DigestAlgorithm.SHA256).
                withSignatureProfile(SignatureProfile.LT).
                withCountry("Estonia").
                withStateOrProvince("Harjumaa").
                withCity("Tallinn").
                withPostalCode("12618").
                withRoles("Developer", "Sportsman").
                buildDataToSign();

Exclude logback.xml from built JAR

We are using Spring Boot in our project and it provides default logback.xml configuration but when we added DigiDoc4J maven dependency it overrided the Spring Boot logback configuration.

I do expect to see something like below:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::             (v1.4.0.M2)

2016-04-26 13:13:38.686  INFO 75023 --- [           main] e.o.siva.sample.SivaDemoApplication      : Starting SivaDemoApplication on MacBook-Pro-2.local with PID 75023 (/Users/*** started by *** in /Users/***)
2016-04-26 13:13:38.691  INFO 75023 --- [           main] e.o.siva.sample.SivaDemoApplication      : No active profile set, falling back to default profiles: default
2016-04-26 13:13:38.745  INFO 75023 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1e730495: startup date [Tue Apr 26 13:13:38 EEST 2016]; root of context hierarchy
2016-04-26 13:13:39.233  INFO 75023 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2016-04-26 13:13:39.407  INFO 75023 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.domingosuarez.boot.autoconfigure.jade4j.Jade4JAutoConfiguration$DefaultTemplateResolverConfiguration' of type [class com.domingosuarez.boot.autoconfigure.jade4j.Jade4JAutoConfiguration$DefaultTemplateResolverConfiguration$$EnhancerBySpringCGLIB$$363caedf] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-04-26 13:13:39.537  INFO 75023 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'defaultSpringTemplateLoader' of type [class de.neuland.jade4j.spring.template.SpringTemplateLoader] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-04-26 13:13:39.540  INFO 75023 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'defaultJadeConfiguration' of type [class de.neuland.jade4j.JadeConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

But the output looks like this:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::             (v1.4.0.M2)

26.04.2016 13:18:02.305 INFO  [main] [e.o.siva.sample.SivaDemoApplication.logStarting:48] - Starting SivaDemoApplication on MacBook-Pro-2.local with PID 75047 (/Users/***/target/classes started by *** in /Users/***)
26.04.2016 13:18:02.308 INFO  [main] [e.o.siva.sample.SivaDemoApplication.logStartupProfileInfo:665] - No active profile set, falling back to default profiles: default
26.04.2016 13:18:02.370 INFO  [main] [o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext.prepareRefresh:580] - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@72057ecf: startup date [Tue Apr 26 13:18:02 EEST 2016]; root of context hierarchy
26.04.2016 13:18:02.718 INFO  [background-preinit] [o.h.validator.internal.util.Version.<clinit>:30] - HV000001: Hibernate Validator 5.2.4.Final

I propose to exclude logback.xml from DigiDoc4J JAR

Where is the timestamp source?

The wikipedia article said this about digidoc

Additionally, during the signing, the certificate validity of each signing party is checked, and a signed timestamp is retrieved, using an OCSP service. The signed timestamp makes it possible to prove at what time a document was signed (as the timestamp is derived from the document hash) which may be important if a card is lost and used to maliciously sign documents.

It didn't give a source of this information. The signer presumably is a trust-worthy authority which will refuse to sign a timastamp that is not current. I wish to amend the wikipedia article since the authority's reliability affects that of estonian e-resident's signatures.

Thought you might know. Thanks!

DSS CommonsDataLoader is not handling not 2XX response codes properly

eu.europa.esig.dss.client.http.commons.CommonsDataLoader

function:
protected byte[] httpGet(String url);
httpResponse = this.getHttpResponse(client, httpRequest, url); byte[] returnedBytes = this.readHttpResponse(url, httpResponse); var7 = returnedBytes;
Basically code returns content only if the response code is 2XX, otherwise content will be null and no proper error will be thrown. Only general message will appear in the logs: "eu.europa.esig.dss.DSSException: Unable to load the LOTL: content is empty".

For instance, if the connection is blocked by proxy, the response will be 401 with message "Blocked By Web Gateway".

Proper behavior: handle all HTTP statuses. If the response code is not 2XX thow exception (3XX should be handled differently if it is the case).

NullPointerException: Error validating signatures on multiple threads:

When logging level is in TRACE, then AsicEContainerValidator gets nullpointer exception in method extractValidatedSignatureErrors().

Problem is based on XadesValidationReportGenerator class in print() method - reports object is null.

https://github.com/open-eid/digidoc4j/blob/develop/digidoc4j/src/main/java/org/digidoc4j/impl/asic/xades/XadesValidationReportGenerator.java

private void print() {
if (this.log.isTraceEnabled()) {
this.log.trace("----------------Validation report---------------");
this.log.trace(this.reports.getXmlDetailedReport());
this.log.trace("----------------Simple report-------------------");
this.log.trace(this.reports.getXmlSimpleReport());
}
}

What's the main class?

I'm running digidoc4j from the command line, but the jar file has no configured Main class:

$ java -jar /tmp/digidoc4j-2.1.0.jar 
no main manifest attribute, in /tmp/digidoc4j-2.1.0.jar

There seems to be a main in DigiDoc4J. Is it the main class to use?

$ java -cp /tmp/digidoc4j-2.1.0.jar org.digidoc4j.main.DigiDoc4J

PROXY Settings

In general, there is one issue regarding proxy configuration.
If I want to use JVM proxy configuration, I need to add the same configuration to the library configuration digidoc4j.yaml.

Problem is in logic of initialization of the HttpClientBuilder, that ignores system properties.

CommonsDataLoader

private HttpClientBuilder configureProxy

In case of implementation and application administration it is confusing, because we need to keep same settings on environment layer and on library layer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.