PHPackages                             setasign/trust-list-fetcher - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. setasign/trust-list-fetcher

ActiveLibrary[Security](/categories/security)

setasign/trust-list-fetcher
===========================

A PHP package that allows you to download or extract all certificates from trust lists such as the EUTL or AATL.

02

Since May 12Compare

[ Source](https://github.com/Setasign/TrustListFetcher)[ Packagist](https://packagist.org/packages/setasign/trust-list-fetcher)[ RSS](/packages/setasign-trust-list-fetcher/feed)WikiDiscussions Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

TrustListFetcher
================

[](#trustlistfetcher)

A PHP package licensed under the [MIT](LICENSE) that allows you to download or extract all certificates from trust lists such as the [EUTL](https://eidas.ec.europa.eu/efda/trust-services/browse/eidas/tls), [Swiss Trust List](https://uri.tsl-switzerland.ch/TrstSvc/TrustedList/schemerules/CH/) (same format as the EUTL) or AATL.

Installation
------------

[](#installation)

You can install the package with [Composer](https://getcomposer.org/):

```
composer require setasign/trust-list-fetcher
```

The package uses classes of the [SetaPDF-Signer](https://www.setasign.com/products/setapdf-signer/) component. A valid license and the correct [composer repository](https://manuals.setasign.com/setapdf-core-manual/installation/#index-2)has to be setup in your composer.json, too.

The root namespace for all classes is `setasign/TrustListFetcher`.

HTTP requests
-------------

[](#http-requests)

All internal HTTP requests are done by a `Client` instance of [`Guzzle`](https://docs.guzzlephp.org/en/stable/)which is expected as an argument for the respective trust list class.

```
$client = new GuzzleHttp\Client([
    'verify' => __DIR__ . '/../assets/cacert-2026-04-16+interm-for-IE.pem'
]);
```

Certificates from the EUTL
--------------------------

[](#certificates-from-the-eutl)

The `EtsiTL` class allows you to download all certificates from the [EUTL](https://eidas.ec.europa.eu/efda/trust-services/browse/eidas/tls/tl/EU) or trust lists from countries or international organizations adopted the same format (defined in ETSI TS 119 612).

Based on the [Official Journal of the European Union (OJEU) on 14 April 2026](https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=OJ:C_202601944) the class starts to load the "List Of Trust Lists" (LOTL) from  and recursively accesses the individual trust lists by the member states.

During this process the integrity and trust of the individual trust list signing certificates are verified. The process has to start with a collection of trusted certificates extracted from the mentioned [OJEU](https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=OJ:C_202601944)which are stored in the file [LOTL-signing-certificates-2026-04-15.pem](assets/LOTL-signing-certificates-2026-04-15.pem).

```
//...
use setasign\SetaPDF2\Signer\PemHelper;
use setasign\SetaPDF2\Signer\X509\Collection;
//...

$trustedCerts = new Collection();
$trustedCerts->add(
    PemHelper::extractFromFile(__DIR__ . '/../assets/LOTL-signing-certificates-2026-04-15.pem')
);
```

Then you can simply initiate an instance:

```
//...
use setasign\TrustListFetcher\EtsiTL;
//...

$eutlFetcher = new EtsiTL($client, $trustedCerts, 'https://ec.europa.eu/tools/lotl/eu-lotl.xml');
```

The real process starts by calling the `fetch()` method, which accepts two callbacks: `$certificateFound` which is executed if a certificate is found and `$certificateError`which is executed if a certificate cannot be interpreted by the `Certificate` instance:

```
//...
use setasign\SetaPDF2\Signer\X509\Certificate;
//...

$eutlFetcher->fetch(
    function (Certificate $certificate) {
        // a certificate was successfully extract
    },
    function (\InvalidArgumentException $e, string $certificate) {
        // the resolved certificate could not be converted to a Certificate instance
    }
);
```

If it is not possible to process all trust lists, the method will throw an `Exception` and the resolved certificates should be seen as incomplete.

NOTE: The whole process can take several seconds or minutes depending on the response times of the individual trust list endpoints.

### Error Handling and Logging

[](#error-handling-and-logging)

Only if the `fetch()` call is executed without any thrown exception, the process can be seen as complete.

To understand what's happening in the whole process the `Eutl` instance allows you access to a default [`Logger`](https://manuals.setasign.com/api-reference/setapdf/c/setasign.SetaPDF2.Signer.ValidationRelatedInfo.Logger)instance by its `getLogger()` method.

You can enable direct output of the logger instance this way:

```
$eutlFetcher->getLogger()->setDirectOutput(true);
```

All logs will be echoed out directly.

If you only want to access the log in case of an exception, just access it in a catch-block:

```
try {
    $eutlFetcher->fetch(
        function (Certificate $certificate) {
            // ...
        },
        function (\InvalidArgumentException $e, string $certificate) {
            // ...
        }
    );

    // commit all resolved certificates

} catch (\Throwable $e) {
    // revert or simply not process all resolved certificates

    echo 'Error: ' . $e->getMessage() . PHP_EOL;
    foreach ($eutlFetcher->getLogger()->getLogs() as $logEntry) {
        echo \str_repeat(' ', $log->getDepth() * 4) . $log->getMessage() . PHP_EOL;
    }
}
```

Certificates from the AATL
--------------------------

[](#certificates-from-the-aatl)

The `Aatl` class allows you to download all certificates from the AATL.

The integrity and timestamp signature of the PDF envelope are validated by a root certificate for Adobe ([Adobe Root CA G2.cer](/assets/Adobe%20Root%20CA%20G2.cer)) and DigiCert ([DigiCert Trusted Root G4.cer](/assets/DigiCert%20Trusted%20Root%20G4.cer)). For this we need a trusted certificate collection:

```
//...
use setasign\SetaPDF2\Signer\X509\Collection;
//...

$trustedCerts = new Collection();
$trustedCerts->addFromFile(__DIR__ . '/../assets/Adobe Root CA G2.cer');
$trustedCerts->addFromFile(__DIR__ . '/../assets/DigiCert Trusted Root G4.cer');
```

Then you can simply initiate an instance:

```
//...
use setasign\TrustListFetcher\Aatl;
//...

$aatlFetcher = new Aatl($client, $trustedCerts);
```

...and call the `fetch()` method to get all certificates from the AATL:

```
//...
use setasign\SetaPDF2\Signer\X509\Certificate;
//...

$aatlFetcher->fetch(
    function (Certificate $certificate) {
        // a certificate was successfully extract
    },
    function (\InvalidArgumentException $e, string $certificate) {
        // the resolved certificate could not be converted to a Certificate instance
    }
);
```

### Error Handling and Logging

[](#error-handling-and-logging-1)

Only if the `fetch()` call is executed without any thrown exception, the process can be seen as complete.

As the `Eutl` instance, the `Aatl` instance also allows you to access a logger instance by its `getLogger()` method.

You can enable direct output of the logger instance this way:

```
$aatlFetcher->getLogger()->setDirectOutput(true);
```

All logs will be echoed out directly.

If you only want to access the log in case of an exception, just access it in a catch-block:

```
try {
    $aatlFetcher->fetch(
        function (Certificate $certificate) {
            // ...
        },
        function (\InvalidArgumentException $e, string $certificate) {
            // ...
        }
    );

    // commit all resolved certificates

} catch (\Throwable $e) {
    // revert or simply not process all resolved certificates

    echo 'Error: ' . $e->getMessage() . PHP_EOL;
    foreach ($eutlFetcher->getLogger()->getLogs() as $logEntry) {
        echo \str_repeat(' ', $log->getDepth() * 4) . $log->getMessage() . PHP_EOL;
    }
}
```

###  Health Score

10

—

LowBetter than 0% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity2

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/78b46f7020bdcd25e761812659988691e50aba9a25b2a48ea33f6137f2fc2536?d=identicon)[Setasign](/maintainers/Setasign)

### Embed Badge

![Health badge](/badges/setasign-trust-list-fetcher/health.svg)

```
[![Health](https://phpackages.com/badges/setasign-trust-list-fetcher/health.svg)](https://phpackages.com/packages/setasign-trust-list-fetcher)
```

###  Alternatives

[mews/purifier

Laravel 5/6/7/8/9/10 HtmlPurifier Package

2.0k18.7M144](/packages/mews-purifier)[paragonie/ecc

PHP Elliptic Curve Cryptography library

24820.0k41](/packages/paragonie-ecc)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
