PDF Signature Validation: LOTL Cache Initialization and Usage
What is the LOTL?
The List of Trusted Lists (LOTL) is a European regulatory framework that provides a centralized registry of trusted certificate authorities across EU member states. Each country maintains its own Trusted List (TL) containing qualified trust service providers and their certificates.
The LOTL acts as a master list that references all national trusted lists, enabling automatic discovery and validation of qualified electronic signatures and seals across Europe. This system ensures legal compliance with the eIDAS regulation and provides a standardized way to verify the trustworthiness of digital certificates issued by different European countries.
Why Use LOTL?
LOTL integration is essential for applications handling European digital signatures and documents requiring legal validity. Without LOTL, you would need to manually maintain and update certificate stores for each European country, track changes to trusted authorities, and ensure compliance with evolving regulatory requirements.
LOTL automates this process by providing:
Regulatory Compliance: Automatic adherence to eIDAS regulation requirements
Cross-Border Validation: Seamless verification of signatures from any EU member state
Reduced Maintenance: No need to manually track certificate authority changes
Legal Validity: Ensures signatures meet qualified electronic signature standards
Up-to-Date Trust Anchors: Automatic updates when countries modify their trusted lists
Who Should Use This?
This LOTL implementation is designed for developers and organizations working with:
Document Management Systems processing European legal documents
Financial Services handling cross-border transactions and contracts
Government Applications requiring eIDAS-compliant signature verification
Healthcare Systems validating medical documents across EU countries
Legal Tech Platforms managing contracts and agreements with European entities
Enterprise Applications that need to verify digitally signed PDFs from European partners
If your application processes digitally signed documents from European sources or needs to ensure legal validity of electronic signatures across EU borders, implementing LOTL validation is recommended.
Overview
This guide demonstrates how to initialize and configure the European List of Trusted Lists (LOTL) cache for PDF signature validation within the iText SDK. For a more detailed technical deep-dive into the subject of the LOTL, head over to: European Union List of Trusted Lists in Validation!
Basic Setup
The following example shows how to configure LOTL cache initialization with customized fetching properties:
Java
public void showCaseCacheInitializationAndSimpleUsage() {
ValidatorChainBuilder builder = new ValidatorChainBuilder();
builder.trustEuropeanLotl(true);
// Configure LOTL fetching properties
LotlFetchingProperties fetchingProperties = new LotlFetchingProperties(new RemoveOnFailingCountryData());
// Initialize global cache and validate signatures
LotlService.initializeGlobalCache(fetchingProperties);
try (PdfDocument document = new PdfDocument(new PdfReader(SRC))) {
SignatureValidator validator = builder.buildSignatureValidator(document);
ValidationReport report = validator.validateSignatures();
System.out.println(report);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
The output of this sample would look something like this:
ValidationReport{validationResult=VALID
reportItems=
ReportItem{checkName='Signature verification check.', message='Validating signature Signature1', cause=null, status=INFO},
ReportItem{checkName='XML Signature verification check.', message='Certificate CN=PORTUGUESE TRUST LIST SCHEME OPERATOR, O=Gabinete Nacional de Segurança, C=PT is trusted. Validation is successful.', cause=null, status=INFO},
ReportItem{checkName='XML Signature verification check.', message='Certificate CN=PORTUGUESE TRUST LIST SCHEME OPERATOR, O=Gabinete Nacional de Segurança, C=PT is trusted. Validation is successful.', cause=null, status=INFO},
CertificateReportItem{baseclass=
ReportItem{checkName='Certificate check.', message='Certificate CN=EC de Chave Móvel Digital de Assinatura Digital Qualificada do Cartão de Cidadão 00003, OU=subECEstado, OU=Cartão de Cidadão, O=AMA - AGÊNCIA PARA A MODERNIZAÇÃO ADMINISTRATIVA I. P., C=PT is trusted, revocation data checks are not required.', cause=null, status=INFO}
certificate=CN=EC de Chave Móvel Digital de Assinatura Digital Qualificada do Cartão de Cidadão 00003, OU=subECEstado, OU=Cartão de Cidadão, O=AMA - AGÊNCIA PARA A MODERNIZAÇÃO ADMINISTRATIVA I. P., C=PT},
ReportItem{checkName='XML Signature verification check.', message='Certificate CN=PORTUGUESE TRUST LIST SCHEME OPERATOR, O=Gabinete Nacional de Segurança, C=PT is trusted. Validation is successful.', cause=null, status=INFO},
CertificateReportItem{baseclass=
ReportItem{checkName='Certificate check.', message='Certificate CN=EC de Chave Móvel Digital de Assinatura Digital Qualificada do Cartão de Cidadão 00003, OU=subECEstado, OU=Cartão de Cidadão, O=AMA - AGÊNCIA PARA A MODERNIZAÇÃO ADMINISTRATIVA I. P., C=PT is trusted, revocation data checks are not required.', cause=null, status=INFO}
certificate=CN=EC de Chave Móvel Digital de Assinatura Digital Qualificada do Cartão de Cidadão 00003, OU=subECEstado, OU=Cartão de Cidadão, O=AMA - AGÊNCIA PARA A MODERNIZAÇÃO ADMINISTRATIVA I. P., C=PT}, }
We see that the ValidationReport
is valid here, if we look at the reportItems
themselves we see the results are that the LOTL Trust List was correctly verified, we have a valid signature check, and we verified the used certificates as well.
Most of the time getValidationResult()
will be enough, and you don’t need to check the reportItems
themselves.
Key Configuration Options
Error Handling Strategy
Configure how the system handles failures when fetching country data:
RemoveOnFailingCountryData() - Skip certificates from countries that fail to load (recommended for most cases)
ThrowExceptionOnFailingCountryData() - Throw exceptions for handling in your code (useful when certificates are critical)
Country Selection
By default, all European countries plus the UK are fetched. You can customize this:
Java
// Fetch specific countries only
fetchingProperties.setCountryNames(LotlCountryCodeConstants.PORTUGAL);
// OR exclude specific countries
fetchingProperties.setCountryNamesToIgnore(
LotlCountryCodeConstants.ITALY,
LotlCountryCodeConstants.UNITED_KINGDOM
);
Cache Configuration
Control cache behavior to optimize performance:
Java
// Set cache staleness period (default: 24 hours)
fetchingProperties.setCacheStalenessInMilliseconds(24 * 60 * 60 * 1000 * 2); // 2 days
// Configure refresh interval (default: 4 times per staleness period)
fetchingProperties.setRefreshIntervalCalculator(
(cacheStalenessInMilliseconds) -> cacheStalenessInMilliseconds / 8); // Every 3 hours
// Disable automatic refresh
fetchingProperties.setRefreshIntervalCalculator(
(cacheStalenessInMilliseconds) -> Integer.MAX_VALUE);
Required Dependencies
Ensure you have the EU Trusted Lists resources dependency in your project:
XML
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>eu-trusted-lists-resources</artifactId>
<version>1.0.0</version>
</dependency>
Important: Without this dependency, you'll encounter a PdfException
stating that European Trusted List resources are not available. If you don’t want to trust our resources, you could always overwrite our implementation, see LotlLoadEuropeanCertificatesFromDifferentSource.java as an example.
Best Practices
Cache Staleness: Don't set cache staleness too low as LOTL fetching is network-intensive, we recommend 1 time a day.
Country Selection: Only fetch certificates for countries you actually need, to improve performance.
Error Handling: Use
RemoveOnFailingCountryData()
unless you have specific requirements for critical certificate handlingRefresh Strategy: The default refresh interval (4 times per staleness period) works well for most applications, this allows for some room for when the service endpoints might be unavailable.