DSS incorporates modules that are loaded in the run time based on the chosen configuration and the input data via a ServiceLoader. This provides a flexibility for an end-user to work only with selected modules and a possibility to expand DSS with custom implementations.
In order to provide a chosen implementation(s) to ServiceLoader
, a file listing all the desired implementations should be created in the resource directory META-INF/services
with a name matching the implemented interface. When merging sources (e.g. creating a Fat JAR module), the files can be lost/overwritten, and should be configured manually (all the required implementations shall be listed).
It is also possible to customize the order of the used implementation, but creating a corresponding file in META-INF/services
directory within your project.
Note
|
If a DSS module(s) implementing a required interface(s) is added to your project’s dependency list, the implementation shall be loaded automatically. |
The following modules are provided with independent implementations:
-
DSS Utils;
-
DSS CRL Parser;
-
DSS PAdES.
Warning
|
At least one implementation shall be chosen. |
The module dss-utils
offers an interface with utility methods to operate on String, Collection, I/O, etc. DSS framework provides two different implementations with the same behaviour :
-
dss-utils-apache-commons
: this module uses Apache Commons libraries (commons-lang3, commons-collection4, commons-io and commons-codec); -
dss-utils-google-guava
: this module uses Google Guava (recommended on Android).
If your integration includes dss-utils
, you will need to select an implementation. For example, to choose the dss-utils-apache-commons
implementation within a Maven project you need to define the following:
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-utils-apache-commons</artifactId>
</dependency>
DSS contains two ways to parse/validate a CRL and to retrieve revocation data. An alternative to the X509CRL
java object was developed to face memory issues in case of large CRLs. The X509CRL
object fully loads the CRL in memory and can cause OutOfMemoryError
.
-
dss-crl-parser-x509crl
: this module uses theX509CRL
java object. -
dss-crl-parser-streams
: this module offers an alternative with a CRL streaming.
If your integration requires dss-crl-parser
, you will need to choose your implementation. For example, to choose the dss-crl-parser-streams
implementation within a Maven project you need to define the following:
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-crl-parser-stream</artifactId>
</dependency>
DSS allows generation, augmentation and validation of PAdES signatures with two different frameworks: PDFBox and OpenPDF (fork of iText). The dss-pades
module only contains the common code and requires an underlying implementation :
-
dss-pades-pdfbox
: PAdES implementation based on Apache PDFBox. Supports drawing of custom text, images, as well as text+image, in a signature field. -
dss-pades-openpdf
: PAdES implementation based on OpenPDF (fork of iText). Supports drawing of custom text OR images in a signature field.
DSS permits to override the visible signature generation with these interfaces:
-
eu.europa.esig.dss.pdf.IPdfObjFactory
; -
eu.europa.esig.dss.pdf.visible.SignatureDrawerFactory
(selects theSignatureDrawer
depending on theSignatureImageParameters
content); -
eu.europa.esig.dss.pdf.visible.SignatureDrawer
.
A new instance of the IPdfObjFactory
can be created with its own SignatureDrawerFactory
and injected in the padesService.setPdfObjFactory(IPdfObjFactory)
. By default, DSS uses an instance of ServiceLoaderPdfObjFactory
. This instance checks for any registered implementation in the classpath with the ServiceLoader (potentially a service from dss-pades-pdfbox
, dss-pades-openpdf
or your own(s)).
DSS allows switching between two implementations of the PDFBox framework: default (original) and native.
-
Native Drawer: A native implementation of PDFBox Drawer, allowing a user to add a vector text, image or combination of text and image to a visible signature field. The native implementation embeds the provided custom text to the inner PDF structure, that makes the text selectable and searchable, but also clearer and smoother in comparison with the raster implementation.
-
Default Drawer: The original drawer implemented on the PDFBox framework, supports displaying of custom text, images, but also text and image combination in a signature field. The implementation does not include the provided custom text to the inner PDF structure, instead of it, the drawer creates an image representation of the provided text, which is added to the signature field (i.e. the text is not selectable and not searchable).
By default, DSS uses the "Native Drawer" as the PDFBox implementation. In order to switch the implementation, that allowed at runtime, you have to set a new instance for PdfObjFactory as following:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/sign/SignPdfPadesBVisibleTest.java[role=include]
Or create a new file META-INF/services/eu.europa.esig.dss.pdf.IPdfObjFactory
within project’s resources, defining the desired implementation (see ServiceLoader for more information).
This implementation is based on the OpenPDF framework. DSS provides two drawers using the implementation:
-
TextOnlySignatureDrawer
- to draw a vector text information within a signature field. The text information is selectable and searchable. -
ImageOnlySignatureDrawer
- to draw an image within a signature field.
Warning
|
DSS provides a limited support of OpenPDF framework, therefore not all features are supported (e.g. text+image drawing). |
With a help of ServiceLoader
, DSS provides a possibility of creation custom mimetype values in addition to the default enumerations defined within MimeTypeEnum
class.
In case a support of new mimetype(s) or file extension(s) is required, a new class defining the new values shall be created implementing the MimeType
interface and an implementation of MimeTypeLoader
handling the logic of new values processing.
See an example of a class mimetypes implementation below:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/CustomMimeTypeLoader.java[role=include]
In order to make the class accessible by ServiceLoader
and visible for DSS, a new file with name eu.europa.esig.dss.enumerations.MimeTypeLoader
shall be created within META-INF/services
directory of your project containing the name of the MimeTypeLoader
implementation:
eu.europa.esig.dss.cookbook.example.CustomMimeTypeLoader
This will load firstly the created class (CustomMimeTypeLoader.java
) and after other available implementations (i.e. MimeTypeEnumLoader
with default mimetypes).
DSS can be used in multi-threaded environments but some points need to be considered like resources sharing and caching. All operations are stateless and this fact requires to be maintained. Some resources can be shared, others are proper to an operation.
For each provided operation, DSS requires a CertificateVerifier
object. This object is responsible to provide certificates and accesses to external resources (AIA, CRL, OCSP, etc.). At the beginning of all operation, CertificateSources and RevocationSources are created for each signature / timestamp / revocation data. Extracted information are combined with the configured sources in the CertificateVerifier. For these reasons, integrators need to be careful about the CertificateVerifier
configuration.
The trusted certificates can be shared between multiple threads because these certificates are static. This means they don’t require more analysis. Their status won’t evolve. For these certificates, DSS doesn’t need to collect issuer certificate and/or their revocation data.
In opposition, the adjunct certificates cannot be shared. These certificates concern a specific signature/validation operation. This parameter is used to provide missing certificate(s). When DSS is unable to build the complete certificate path with the provided certificates (as signature parameters or embedded within a signature), it is possible to inject certificates that are not present. These certificates are not necessarily trusted and may require future "modifications" like revocation data collection, etc.
In case of multi-threading usage, we strongly recommend caching of external resources. All external resources can be cached (AIA, CRL, OCSP) to improve performances and to avoid requesting too much time the same resources. FileCacheDataLoader and JdbcCacheCRLSource can help you in this way.
See section [CachingUseCases] of the Annex for complete examples of caching revocation data, certificates and trusted lists.
DSS provides the following JAXB modules with a harmonized structure :
-
dss-policy-jaxb
- defines validation policy JAXB model; -
dss-diagnostic-jaxb
- defines Diagnostic Data JAXB model; -
dss-detailed-report-jaxb
- defines Detailed Report JAXB model; -
dss-simple-report-jaxb
- defines Simple Report JAXB model; -
dss-simple-certificate-report-jaxb
- defines Certificate Simple Report JAXB model.
All modules share the same logic and have the following structure (where *** is a model name):
dss-***-jaxb
-
/src/main/java
-
eu.europa.esig.dss.***
-
-
***.java
- wrapper(s) which eases the JAXB manipulation -
…
-
***Facade.java
- class which allows marshalling/unmarshalling of jaxb objects, generation of HTML/PDF content, etc. -
***XmlDefiner.java
- class which contains the model definition (XSD, XSLT references, ObjectFactory) -
/jaxb
- generated on compile time-
Xml***.java
- JAXB model -
…
-
-
/src/main/resources
-
/xsd
-
-
***.xsd
- XML Schema (XSD) for the Detailed Report model -
binding.xml
- XJC instructions to generate the JAXB model from the XSD
-
/xslt
-
-
/html
-
***.xslt
- XML Stylesheet for the HTML generation
-
-
/pdf
-
***.xslt
- XML Stylesheet for the PDF generation
-
-
In the main classes, a Facade
is present to quickly operate with the JAXB objects (e.g. marshall, unmarshall, generate the HTML/PDF, validate the XML structure, etc.).
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/SignedDocumentValidatorTest.java[role=include]
An XmlDefiner
is also available with the access to the embedded XML Schemas (XSD), the XML Stylesheets (XSLT) to be able to generate the HTML or the PDF content (for DSS specific JAXB) and the JAXB Object Factory.
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/SignedDocumentValidatorTest.java[role=include]
It is possible to programmatically create or/and edit an XML Trusted List using the JAXB module.
Below is an example of how to use JAXB modules to create a trusted list (not complete solution):
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/CreateTLSnippet.java[role=include]
And an example how to modify an existing Trusted List (e.g. change its version):
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/CreateTLSnippet.java[role=include]
You can also use JAXB modules not only for the content creation or changing, but also in order to verify the conformity of an XML document against its XSD schema.
For example, in order to validate a XAdES signature conformance against 1.3.2 XSD schema, you can use the corresponding class XAdES319132Utils
:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/sign/SignXmlXadesBPropertiesTest.java[role=include]
The report modules (namely: dss-simple-report-jaxb
, dss-simple-certificate-report-jaxb
and dss-detailed-report-jaxb
) contain XSLT style sheets each for final reports generation:
-
Bootstrap 4 XSLT for HTML report;
-
PDF XSLT for PDF report.
Note
|
Since DSS 5.9 only Bootstrap 4 XSLT is provided within the framework for HTML report generation. |
In order to generate a report with a selected style sheet you need to call a relevant method in a Facade class (see classes definition above):
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/StylesheetSnippet.java[role=include]
Otherwise, in case you need to customize the transformer, you can create a report by using an XmlDefiner
:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/StylesheetSnippet.java[role=include]
The dss-diagnostic-jaxb
module contains an XSLT stylesheet that creates an SVG image from an XML document in order to visually represent the signature at validation time.
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/SVGGenerationSnippet.java[role=include]
The framework allows custom configuration of XML-related modules for enabling/disabling of XML securities (e.g. in order to use Xalan or Xerces).
Warning
|
We strongly do not recommend disabling of security features and usage of deprecated dependencies. Be aware: the feature is designed only for experienced users, and all changes made in the module are at your own risk. |
The configuration is available for the following classes:
-
javax.xml.parsers.DocumentBuilderFactory
with aDocumentBuilderFactoryBuilder
- builds a DOM document object from the obtained XML file and creates a neworg.w3c.dom.Document
; -
javax.xml.transform.TransformerFactory
with aTransformerFactoryBuilder
- loads XML templates and builds DOM objects; -
javax.xml.validation.SchemaFactory
with aSchemaFactoryBuilder
- loads XML Schema; -
javax.xml.validation.Validator
with aValidatorConfigurator
- configures a validator to validate an XML document against an XML Schema.
All the classes can be configured with the following methods (example for TransformerFactory
):
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/XMLSecuritiesConfigTest.java[role=include]
The javax.xml.parsers.DocumentBuilderFactory
, that allows XML files parsing and creation of DOM org.w3c.dom.Document
object, can be configured with the following methods:
Note
|
Since DSS 5.9 the configuration of javax.xml.parsers.DocumentBuilderFactory has been moved from DomUtils to a new singleton class DocumentBuilderFactoryBuilder .
|
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/XMLSecuritiesConfigTest.java[role=include]
The class XmlDefinerUtils
is a singleton, therefore all changes performed on the instance will have an impact to all calls of the related methods.
See section [Alerts] in chapter Annex for more information on alerts.
Since DSS 6.2
it is possible to configure the memory usage on PDF reading. The feature is useful on document signing or validation, when a smart memory usage is crucial, for instance when processing big PDF files.
The configuration can be done using a PdfMemoryUsageSetting
class, as shown below:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/snippets/PAdESWithIPdfObjFactoryConfiguration.java[role=include]
Note
|
PdfMemoryUsageSetting is only supported in methods within PAdESService and PDFDocumentValidator .
|
Since version 5.11, DSS provides a possibility to configure a way temporary objects are created within the core code.
DSSResourcesHandler
is responsible for implementation of created temporary objects during the execution, e.g. in memory or in a temporary file.
Note
|
DSSResourcesHandler is only supported in methods within PAdESService (i.e. signature creation, extension, screenshot generation, etc.) and ZipUtils (ASiC generation).
|
The DSSResourcesHandler
interface provides the following methods:
-
createOutputStream()
- creates a newOutputStream
, to be used as a data buffer; and -
writeToDSSDocument()
- writes the created earlierOutputStream
to a correspondingDSSDocument
implementation.
The DSSResourcesHandler
implements Closable
interface, therefore it is able to remove temporary objects when closing or exiting the try block.
In order to create a DSSResourcesHandler
an implementation of DSSResourcesHandlerBuilder
should be used. DSS provides the following implementations of DSSResourcesHandlerBuilder
interface:
-
InMemoryResourcesHandlerBuilder
- creates aByteArrayOutputStream
to be used as a data buffer (e.g. storing a signed PDF) and producesInMemoryDocument
containing the byte array of a created document. -
TempFileResourcesHandlerBuilder
- creates a temporaryFile
in the local filesystem, storing in it the temporary data and produces aFileDocument
as an output, when applicable. The implementation removes the temporary files when the file is not required outside the method or when finishing JVM.
Note
|
InMemoryResourcesHandlerBuilder is used by default in DSS, working with data in memory.
|
To define the resources handler for PAdES processing, the corresponding DSSResourcesHandlerBuilder
has to be provided to an instance of IPdfObjFactory
used within a PAdESService
. An example below demonstrates a signature creation using in temporary file processing:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/sign/SignPdfWithTempFileTest.java[role=include]
Warning
|
Based on the implementation, certain objects are still have to be processed in memory (e.g. with PdfBox or iText document readers). |
Since DSS 6.1
a DSSResourcesHandler
may also be used for ASiC creation, allowing to configure direct ASiC creation within a FileSystem as below:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/sign/SignASiCEWithXAdESWithTempFileTest.java[role=include]
For parsing and creation of ZIP archives a special class ZipUtils
is provided. This is a singleton class, and its behavior can be customized using an implementation of ZipContainerHandler
interface. An implementation of ZipContainerHandler
can be provided in runtime and the defined class will be used on all calls of ZipUtils
across DSS’s code
By default, an instance of SecureContainerHandler
is used, allowing to parse ZIP container securely, by reporting a presence of a ZIP-bomb (see 42.zip) and/or malicious documents within a given archive.
Below you can find the configuration available in SecureContainerHandler
:
link:../../../test/java/eu/europa/esig/dss/cookbook/example/sign/SignOneFileWithASiCSBTest.java[role=include]