Skip to main content
Skip table of contents

European Union List of Trusted Lists in Validation

European Union List of Trusted Lists Explanation

The European Union's List of Trusted Lists (LOTL), is a central, signed XML file that contains links to the individual trusted lists published by each EU and EEA Member State. These Member State lists identify trust service providers and the trust services they offer, such as digital signatures and seals, ensuring their compliance with EU eIDAS regulations and facilitating the validation of electronic signatures.

In simple terms, the European Union List of Trusted Lists (LOTL in future references) is an XML file, which contains country-specific Trusted Lists (TL). Those country-specific TLs contain various certificates, which are considered trustworthy and can be used during PDF signature validation.

However a responsible validation processor should not just download those certificates, without confirming the source itself is trusted. For that purpose, both the main LOTL file and country-specific TLs are signed. Trusted certificates mentioned in those TLs are only supposed to be trusted, if the corresponding XML files are successfully validated.

And now we are happy to announce, iText supports retrieval, validation and usage of European Union List of Trusted Lists!

Why this may be useful

In order to be able to validate anything signature related, a chain of trust must be established. Without going too deep into the details, any chain of trust eventually ends with some kind of certificate which is supposed to be unconditionally trusted.

Before this feature was introduced, users were forced to provide trusted certificates manually. Even though this is still possible, many may find such a requirement slightly inconvenient. So, now you are not obliged to do that. The European Union List of Trusted Lists can be retrieved, validated and parsed to provide root trusted certificates instead.

API Entry point and overall introduction

In order to start using this feature, the first step would be to enable it in the ValidatorChainBuilder API. All you need to do is to call the ValidatorChainBuilder#trustEuropeanLotl(boolean)[1] method with the true parameter. That’s it. From now on any validation performed with validators created out of this builder will use the European Union Trusted Lists. However, there is one additional step which is required.

Retrieving, parsing and validating huge XML files containing thousands of certificates is a heavyweight operation, that’s why we don’t want it to happen too often. For exactly this reason, iText stores the data in a specific cache. By default this cache is static, and can be accessed from anywhere in your project. This way we minimize processing time and memory consumption as much as possible. That’s why, before Trusted Certificates are used in your validation process, the cache must be initialized.

In order to do so, the static LotlService#initializeGlobalCache(LotlFetchingProperties)method has to be called. This step is required before any validation with European Union LOTL usage feature takes place. If the cache is not initialized, a corresponding exception will occur.

We strongly advise to perform this operation in advance, so that actual PDF validation takes as little time as possible. We also forbid calling this method a second time, to avoid potential accidental cache re-initialization.

But what are those LotlFetchingProperties? Well, this is how details of LOTL parsing and usage can be configured. Let’s take a deeper look.

First of all, creation of LotlFetchingProperties requires IOnFailingCountryLotlData to be provided as a parameter. This strategy defines the behavior, in case of any country specific sources being unavailable.

It’s important to remember, iText has no influence over external resources being fetched and used in this feature.

Two strategies are already defined in our API. RemoveOnFailingCountryData and ThrowExceptionOnFailingCountryData, but of course custom ones can be created to fulfill your specific needs[1].

  • RemoveOnFailingCountryData basically ignores possible failures in country-specific TL retrieval and parsing. In case of any failure, the Trusted List is ignored and the process continues.

  • ThrowExceptionOnFailingCountryData on the other hand, throws an exception in case of any failure.

And once again, this strategy is only relevant in case of country-specific TL failures. If something else fails, most likely there is no other option than to throw an exception, because the whole chain is no longer trusted. So, we want to make sure the user is aware of such behavior.

In addition to the strategy, which is required, there are couple of optional configurations[1].

  • country names (schema names) - this configuration affects which country-specific TLs are expected to be used. Possible values can be found in the LotlCountryCodeConstants class. Both inclusion and exclusion options are provided.

  • service types - this configuration affects which certificates are supposed to be used from Trusted Lists. Each certificate in the list contains a service type field, which defines the scope in which the certificate is supposed to be trusted. Some certificates are only expected to be used to sign timestamps or timestamp chains, others are defined for OCSPs, etc… Using this API, users can re-configure which service types are suppose to be used during the validation. However, we still treat those according to their meaning. To change that, more low-level configuration is required, which involves an LotlTrustedStore override.

  • cache staleness - this configuration defines how stale your data can be, before it can no longer be used. We’ll discuss it in more details a bit later. By default the value is 24 hours.

  • refresh interval calculator - this function defines how often your data is supposed to be refreshed. We’ll discuss it in more details soon. By default the value is 23% of staleness

Data Refresh

The next topic we want to address, is how to update LOTL related data. We already mentioned that it’s not possible to call LotlService#initializeGlobalCache(LotlFetchingProperties) more than once. We also already established that the data fetch is quite a heavy operation, so we don’t want to do that every time a validation is performed.

For that reason, a cache was created which stores all the data. However, it’s obviously possible that something might change if you run your application for a significantly long time. That’s why it’s important to update the data from time to time. And we take care of this ourselves as well.

Upon first cache initialization, a specialized background task is set up which periodically performs a cache update. The operation which happens behind the scenes is exactly the same as on the first initialization. We just retrieve everything from scratch, parse and validate it, and if everything is fine, update the cache.

By default this happens each 5.52 hours, but this can be configured in the LotlFetchingProperties class by providing a custom refresh interval calculator.

But what happens if some data is not available at the moment of refreshing? Let’s say we were able to successfully get France’s Trusted Certificates on first initialization, but for some reason we weren’t able to update them on refreshing. You as a user might still want to use old data, at least for some time. This is why we created the staleness parameter.

The staleness parameter can be configured via the LotlFetchingProperties setting. This parameter establishes the maximum permissible age for data to be considered valid and usable. By default, staleness is set to 24 hours, meaning the data remains usable for that period if refreshing fails.

What will happen after? The very same IOnFailingCountryLotlData we asked you to provide will be used in case of country-specific data being too stale. For any other, non country-specific data, an exception will be thrown.

Custom configurations for custom validations

Up to this point we have described the creation, initialization, and use of the static LotlService. That means that only single LotlFetchingProperties can be provided for such LotlService. But how can I have multiple different configurations depending on what I want to validate?

Let’s say for one specific validation, only Germany’s certificates should be used, but for another set of documents, Spain’s certificates are needed. Well, in order to have custom validations, custom LotlService instances can be created.

The ValidatorChainBuilder API allows you to provide your own LotlService instances with ValidatorChainBuilder#withLotlService. By default, a statically defined one is used.

So if you want to have multiple different LOTL configurations, just create multiple LOTL Services with different LotlFetchingProperties, initialize those by calling LotlService#initializeCacheand you are good to go.

Just remember, each LotlService uses it’s own cache, so be careful not to store the same data multiple times. Additionally, each LotlService sets up their own refreshing task. That’s why when you are done with a specific LotlService, we need to clean up everything.

For this purpose LotlServiceimplements AutoCloseable in Java and IDisposable in C#. Don’t forget to manage your resources 🙂.

Root Trusted Certificates for LOTL files

As we’ve already mentioned, LOTL files are presented as signed XML files. In order to be able to validate these, some trusted certificates are needed to establish trust.

But wait, the main idea of a LOTL file is to provide us with trusted certificates. And now you are saying we need more trusted certificates, to validate LOTL files? Well, yes, trusted certificates from the LOTL file cannot be used to validate the exact same LOTL file.

That’s why the European Union additionally shares a list of trusted certificates, to be used to validate LOTL files. These are provided in the Official Journal of the European Union.

iText needs those trusted certificates, but retrieving them from the Internet for every validation doesn’t sound like a great idea; the Journal isn’t signed, so there is no way to be sure it wasn’t compromised if you retrieve it on runtime from the internet.

Instead, we pre-downloaded them in a specialized repository. It’s called eu-trusted-lists-resources and can be found in Maven and NuGet. This repository contains the list of trusted certificates and URL addresses from which the List of Trusted Lists should be retrieved.

The dependency to this repository is not provided in iText by default, so in order to be able to use the LOTL feature you’ll need to either provide such a dependency, or configure your own source of Official Journal trusted certificates.

In order to configure a custom source, LotlService#withEuropeanResourceFetcher can be used. You have the choice to either be responsible for providing this source of trust yourself, or rely on iText to do so.

Even though these Journal trusted certificates are meant to remain the same for years, eventually they will be updated as well. If outdated trusted certificates are used for some reason, the LOTL file will not be successfully validated and the whole feature won’t work anymore. That’s why it’s crucial to be able to update them in time.

But don’t worry, this is not going to happen out of the blue. The mechanism of updating involves safe measures—including a transition period—to ensure that users and relying parties have enough time to adjust their code base and resources.

A new version of eu-trusted-lists-resources library is expected to be released each time those resources are updated. A corresponding exception should be expected to be thrown if the resources are outdated.

However, if LOTL certificates are suddenly no longer successfully validated, please check that the Official Journal trusted certificates are up to date.

After new resources are released, the transition period begins, which usually takes 15 days. During this time, both the new and old resources are applicable for validation. During this time, iText will produce a corresponding warning log message. It is crucial to update the resources during this time, since after the transition period ends it is most likely LOTL validation will no longer be successful.

Possible problems you may encounter

Since this whole feature strongly depends on a remote infrastructure maintained by European Union parties, iText cannot guarantee complete stability. However, we can instead warn you about possible problems and solutions:

SSLHandshakeException being thrown on country specific fetching in Java

In order to establish trust for HTTPS connection, Java uses a pre-downloaded list of trusted certificates. These are embedded in your JDK. However, if the JDK version is not up to date, it might be possible that some certificates are missing and the HTTPS connection cannot be trusted.

Because of this, you may suddenly be faced with SSLHandshakeExceptionor its analogs. There are multiple ways to fix this; ideally you would want to update your JDK to include all the necessary trusted certificates. However, if this is not possible for some reason, there are some alternatives.

Many of those will include the creation of a custom IResourceRetreiver, which can be set using LotlService#withCustomResourceRetriever.

WebException being thrown on country specific fetching

Apart from an SSL certificate not being trusted, there is one more potentially problematic scenario. Some authorities may not allow you to establish a connection if a user agent is not set up.

By default iText uses an empty user agent. This should also be configured through the use of custom IResourceRetreiver and LotlService#withCustomResourceRetriever.

Ahead of Time compilation

In the case of the GraalVM JDK, there’s a known compatibility issue with the 3rd-party-dependency in GraalVM environments. It’s fairly easy to solve this by providing the missing configurations, which is carefully explained in this article: Supporting org.apache.xml.security in GraalVM.

An additional point relates to the Apache Santuario library which will not work out of the box, and so requires manual adjustment for compatibility with GraalVM. The required configuration options can be found in this commit: GitHub - Finalize LOTL API Add support for GraalVM, however, we are currently working on pushing this to the Oracle GraalVM Reachability Metadata repository so that this workaround will not be necessary.

Samples

Java

.NET

Description

LotlSimpleSignatureValidation.java

LotlSimpleSignatureValidation.cs

This sample provides the simplest use case possible, with all the possible high-level configuration options.

LotlValidationWithLocalFirstFileAccess.java

LotlValidationWithLocalFirstFileAccess.cs

LOTL endpoint might be unstable, so to avoid going over the network to fetch them, we showcase a simple local file resolution example.

With a little imagination you can implement your own fully fledged local storage implementation.

LotlLoadEuropeanCertificatesFromDifferentSource.java

LotlLoadEuropeanCertificatesFromDifferentSource.cs

If you want full control over the certificates used as trust anchors in the LOTL signature validation, this sample showcases how to setup certificates, and not to rely on our provided resources.

References

  1. For more detailed API dive, please, see https://api.itextpdf.com/iText/java/9.3.0/com/itextpdf/signatures/validation/lotl/package-summary.html for Java, or https://api.itextpdf.com/iText/dotnet/latest/namespacei_text_1_1_signatures_1_1_validation_1_1_lotl.html for .NET.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.