Enterprise edycja
ASiC trust binding — deep reference
Ta treść nie jest jeszcze dostępna w Twoim języku.
At a glance
Section titled “At a glance”This page is the deep reference for the ASiC trust binding surface in NextPDF Enterprise. It documents the supported public API, its behavior contract, its reason codes, and its failure modes. For the workflow-level guide and worked examples, see ASiC trust binding.
The surface answers one narrow question: at a stated validation time, does the signing certificate taken from an ASiC container signature parse, fall within its own validity period, and carry a signature that verifies against at least one anchor in the supplied anchor bundle? NextPDF\Enterprise\Security\Asic\AsicTrustBinder exposes two public methods, verify() and verifyAgainstBundle(), and both assert the Enterprise capability enterprise.signatures.batch_validate. verify() takes the signer PEM, a TslDocument, and a validation time, and derives an anchor bundle from that trusted list through NextPDF\Enterprise\Security\Tsl\TslTrustAnchorProvider::buildBundle(); verifyAgainstBundle() takes the signer PEM, a pre-built EnterpriseCaTrustAnchorBundle, and a validation time. Each returns an AsicTrustBindingResult — a trusted/untrusted verdict, the anchor bundle version it decided against, and machine-readable reason codes. buildBundle() raises NextPDF\Enterprise\Security\Tsl\TslParseException when the trusted list is not fresh or its granted CA/QC set is empty.
One boundary is deliberate. This API does not parse ASiC containers: its inputs are the already-extracted signer PEM, the trusted list (or a pre-built bundle), and the validation time. Your tooling opens the container, walks its META-INF manifests, and extracts the signing certificate before calling this API.
trusted = true is a bounded statement about three checks: the signer certificate parsed, its validity period included the supplied validation time, and its signature verified against at least one anchor in the bundle when that anchor was loaded on its own as the candidate issuer. Everything else is out of scope for this call, as an observed property of the code:
- The binder loads no intermediate certificates and assembles no certificate path — each anchor is tried singly, and a bundle with no matching anchor yields
no_anchor_chain. - It performs no revocation lookup: there is no CRL or OCSP call in the binder or in its anchor-derivation path.
- It does not verify the ASiC/CAdES/XAdES content signature over the container — its only cryptographic input is the signer certificate, not the signed data. Validate the signature value with Signature verification.
- It produces no qualification or legal-effect classification of the signer: the result object carries only a
trustedflag, the anchor bundle version, and reason codes.
Availability & licensing
Section titled “Availability & licensing”Both public entry points, verify() and verifyAgainstBundle(), begin by asserting the Enterprise capability code enterprise.signatures.batch_validate (CapabilityCode::EnterpriseSignaturesBatchValidate); TslTrustAnchorProvider::buildBundle() asserts the same capability before deriving any anchor. The classes documented here live under the NextPDF\Enterprise\Security\Asic and NextPDF\Enterprise\Security\Tsl namespaces. Compare editions.
Public API surface
Section titled “Public API surface”| Symbol | Parameters | Behavior | Returns | Throws | Notes |
|---|---|---|---|---|---|
AsicTrustBinder::verify | string $signerCertPem, TslDocument $tsl, DateTimeInterface $validationTime | Asserts the capability and verifies the signer against an anchor bundle derived from the supplied TSL via buildBundle() | AsicTrustBindingResult | TslParseException when the TSL is not fresh (stale or non-canonical NextUpdate) or its granted CA/QC set is empty | The validation time is an explicit parameter with no default |
AsicTrustBinder::verifyAgainstBundle | string $signerCertPem, EnterpriseCaTrustAnchorBundle $bundle, DateTimeInterface $validationTime | Asserts the capability and verifies the signer against the supplied bundle | AsicTrustBindingResult | Not specified here | Construct the bundle via TslTrustAnchorProvider::buildBundle |
AsicTrustBindingResult::__construct | bool $trusted, string $anchorBundleVersion, array $reasons | Immutable verdict value object | — | Not specified here | final readonly; $reasons is list<non-empty-string>; all three properties are public |
TslTrustAnchorProvider::buildBundle | TslDocument $tsl, DateTimeImmutable $now | Asserts TSL freshness and filters to granted CA/QC services; produces a bundle versioned tsl-<territory>-seq<N> | EnterpriseCaTrustAnchorBundle | TslParseException (stale, non-canonical NextUpdate, or empty granted CA/QC set) | Produces the anchor bundle verify() decides against |
EnterpriseCaTrustAnchorBundle::__construct | array $anchorsPem, string $bundleVersion, string $bundleSha256 | Validates the 64-hex digest and each PEM, then hash_equals the supplied digest against the one recomputed over the canonicalised anchors | — | InvalidArgumentException (digest not 64-hex, a non-PEM entry, or digest mismatch) | Prefer buildBundle over hand construction |
EnterpriseCaTrustAnchorBundle::computeBundleSha256 | array $anchorsPem | Produces the SHA-256 digest the bundle constructor validates | non-empty-string (hex SHA-256) | Not specified here | Static helper |
EnterpriseCaTrustAnchorBundle::containsFingerprint | string $anchorDerSha256Hex | Returns whether the supplied hex string equals one of the bundle’s per-anchor SHA-256 digests, each computed over that anchor’s DER body | bool | Not specified here | Membership test, not signature verification |
The Throws column records exception paths visible in the source and is not exhaustive: Not specified here means this page does not enumerate an exception for that row; it is not a no-throw guarantee. For example, the capability assertion at each entry point can reject an unlicensed caller.
public function verify( string $signerCertPem, TslDocument $tsl, DateTimeInterface $validationTime,): AsicTrustBindingResult
public function verifyAgainstBundle( string $signerCertPem, EnterpriseCaTrustAnchorBundle $bundle, DateTimeInterface $validationTime,): AsicTrustBindingResultfinal readonly class AsicTrustBindingResult{ public function __construct( public bool $trusted, public string $anchorBundleVersion, public array $reasons, ) {}}public function buildBundle( TslDocument $tsl, DateTimeImmutable $now,): EnterpriseCaTrustAnchorBundleReason codes
Section titled “Reason codes”AsicTrustBindingResult::$reasons is a list<non-empty-string> of machine-readable codes.
| Reason code | Verdict | Meaning |
|---|---|---|
anchor_signature_match | trusted | The signer certificate verifies against an anchor in the supplied bundle. |
no_anchor_chain | untrusted | No anchor in the bundle verifies the signer certificate. |
signer_cert_expired | untrusted | The validation time falls after the certificate’s notAfter. |
signer_cert_not_yet_valid | untrusted | The validation time falls before the certificate’s notBefore. |
cannot_parse_signer_cert | untrusted | The supplied PEM does not load as an X.509 certificate. |
$anchorBundleVersion records the bundle version label used for the decision; the binder copies it from the bundle it decided against. For a bundle produced by TslTrustAnchorProvider::buildBundle(), this label has the form tsl-<territory>-seq<N> (for example tsl-eu-seq42); for a bundle you construct directly, it is the bundleVersion string passed to the constructor.
Behavior contract
Section titled “Behavior contract”- Capability. Both
verify()andverifyAgainstBundle()assert theenterprise.signatures.batch_validatecapability. - TSL freshness.
verify()derives its anchor bundle from the supplied trusted list throughbuildBundle(), which asserts the list is fresh. A list whoseNextUpdatehas passed, or whoseNextUpdateis not a canonical UTC value, raisesTslParseException. - Anchor derivation.
buildBundle()filters the trusted list to services that are both in granted status (STATUS_GRANTED) and of the CA/QC service type (TYPE_CA_QC). A list whose granted CA/QC set is empty raisesTslParseExceptionrather than yielding an empty bundle. - Bundle version and integrity. A bundle produced by
buildBundle()is versionedtsl-<territory>-seq<N>. The constructor recomputes a SHA-256 over the canonicalised anchor PEMs andhash_equalsit against the suppliedbundleSha256, throwingInvalidArgumentExceptionon a mismatch;EnterpriseCaTrustAnchorBundle::computeBundleSha256()produces exactly the digest that check validates. - Signer parsing. The signer PEM is parsed once with phpseclib’s X.509 parser. A PEM that does not load yields
cannot_parse_signer_cert. - Validity check. The signer certificate’s validity period must include the validation time;
validateDatedistinguishes a not-yet-valid signer (signer_cert_not_yet_valid) from an expired one (signer_cert_expired). - Anchor verification. Each anchor in the bundle is loaded on its own as a fresh candidate CA (
loadCA) and the signer certificate’s signature is checked against it (validateSignature); a matching anchor yieldsanchor_signature_match, and a bundle with no matching anchor yieldsno_anchor_chain. The binder loads no intermediate certificates and assembles no multi-certificate path. - Exceptions and verdicts. A signer problem is reported as an
AsicTrustBindingResultcarrying a reason code, not by throwing. Two exception paths are visible in the source:TslParseExceptionfrombuildBundle()(a non-fresh list, a non-canonicalNextUpdate, or an empty granted CA/QC set) andInvalidArgumentExceptionfrom theEnterpriseCaTrustAnchorBundleconstructor (a digest that is not 64-hex, a non-PEM entry, or a digest that does not match the anchor set). This list is not exhaustive — the capability assertion, for instance, can reject an unlicensed caller. - Container parsing. The inputs are the extracted signer PEM, the trusted list (or a pre-built bundle), and the validation time; container parsing is the caller’s responsibility. A CAdES baseline generator places the signing certificate in
SignedData.certificates, so your container tooling can extract it.
Edge cases & failure modes
Section titled “Edge cases & failure modes”- Validation time is mandatory. There is no silent
nowdefault; the caller passes the validation time, andvalidateDatecompares the signer certificate’s validity period against it. A signer that passed at one instant reportssigner_cert_expiredwhen validated at a later instant pastnotAfter, andsigner_cert_not_yet_validbeforenotBefore. - A stale TSL raises
TslParseException.TslParseExceptionfromverify()orbuildBundle()signals that the trust source is unusable. Treat it as an operational failure — refresh the list — not as a signer rejection. NextUpdatemust be canonical UTC. A non-canonical value raisesTslParseException.- Empty granted CA/QC set. A list whose granted CA/QC services are all filtered out raises
TslParseExceptionrather than producing an empty bundle. - Malformed signer input. A PEM that does not parse returns
cannot_parse_signer_cert; a not-yet-valid certificate is distinguished from an expired one. - Hand-built bundles. Constructing
EnterpriseCaTrustAnchorBundledirectly with a digest that is not 64-hex, a non-PEM entry, or a digest that does not match the anchor set raisesInvalidArgumentException. PreferbuildBundle(), which computes a matching digest for the anchors it extracts. - A fresh, validated TSL is a precondition. Pass a trusted list that has already been validated through the trusted-list pipeline (see Trusted lists).
- This is one layer, not the whole validation. The binder performs no revocation lookup (no CRL or OCSP call) and does not verify the CAdES/XAdES signature value over the container content. Verify the signature cryptographically with your signature tooling and add revocation checking per your policy.
Conformance
Section titled “Conformance”| Claim | Standard | Clause |
|---|---|---|
| An ASiC-E container associates data files with signature files, each carrying CAdES or XAdES signatures over its own file set. | ETSI EN 319 162-1 | §4.4.1 |
| A validation application identifies the signature reference file from each ASiCManifest; container parsing precedes this API. | ETSI EN 319 162-1 | §4.4.4.2 |
A CAdES baseline generator includes the signing certificate in SignedData.certificates, so a verifier can extract it. | ETSI EN 319 122-1 | Clause 6 |
| A trusted list whose Next update instant has passed is expired and is discarded. | ETSI TS 119 612 | §5.3.15 |
| The CA/QC service-type URI identifies trust services issuing qualified certificates; only these seed the anchor set. | ETSI TS 119 612 | §5.5.9.1 |
| Signature validation validates the signing certificate at the validation time, which is an explicit input. | ETSI EN 319 102-1 | §5.2.6.1 |
| Whether the validation time falls within the signing certificate’s validity period is a distinct validation step. | ETSI EN 319 102-1 | §5.2.6.2 |
| Path validation requires the certificate validity period to include the time being tested. | RFC 5280 | §6.1.3 |
The validity period runs from notBefore through notAfter inclusive, distinguishing not-yet-valid from expired. | RFC 5280 | §4.1.2.5 |
All clauses are paraphrased; NextPDF does not reproduce normative text. Support is not conformance, and conformance is not certification. NextPDF implements the checks this page describes; using this API does not by itself make your output “qualified” or legally effective under eIDAS or any other regime. Whether a complete validation process meets a given legal or procurement requirement is a determination for your assessors.
Development notes
Section titled “Development notes”AsicTrustBindingResultis afinal readonlyvalue object. Construct results directly in unit tests; build bundles throughbuildBundle()or derive their digest with the staticEnterpriseCaTrustAnchorBundle::computeBundleSha256()helper so the digest is consistent.verify()derives an anchor bundle from the TSL it is given viabuildBundle();verifyAgainstBundle()takes an already-built bundle instead.- Recommended boundary tests: a signer issued by a listed anchor (trusted), a signer under an unlisted issuer (
no_anchor_chain), a malformed signer PEM (cannot_parse_signer_cert), a validation time pastnotAfter(signer_cert_expired) and beforenotBefore(signer_cert_not_yet_valid), and a stale trusted list (TslParseException). - The caller supplies the validation time;
validateDatecompares the signer certificate’s validity period against that time. The binder does not determine whether a timestamp is qualified or otherwise trustworthy — that determination is the caller’s responsibility.
See also
Section titled “See also”- ASiC trust binding — the capability page: workflow, configuration, and worked examples.
- Trusted lists — deep reference — fetch, authenticate, and parse the TSL that feeds the anchor provider.
- Signature verification — deep reference — the Enterprise verification surface for PDF signatures.
- Security — deep reference — the combined Enterprise security surface.
- HSM signing — deep reference — hardware key custody for the signing side.
- Core security
- How a digital signature proves who signed — first-principles background.
- Long-term validation — why validation time and preserved evidence matter.
Publication boundary
Section titled “Publication boundary”This page documents externally observable behavior and the supported public API surface only. Internal namespace paths beyond the published entry points, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.