Validating a signature properly
Spec: RFC 5280, §6 RFC 5280 §6 Spec: RFC 6960 RFC 6960 Spec: RFC 5652 RFC 5652 Evidence: Test-backed
At a glance
Section titled “At a glance”“The signature is valid” usually means one thing was checked: the math added up. A correct validation checks at least five independent things, and any one of them can fail in a way that makes a green checkmark meaningless. This page gives the full check set, and explains why a partial answer is a dangerous answer.
Why this matters
Section titled “Why this matters”A single boolean is the most dangerous output in this entire topic. It invites a reader to treat “valid” as “trustworthy,” when “valid” might only mean the bytes were not altered — by a key from a certificate that expired three years ago, was revoked last month, and chains to no authority you recognize. Every one of those is a separate check. Software that reports one boolean has silently decided which checks mattered, and it decided for you. In a regulated or contractual setting, “the tool said valid” is not a defense if the tool only verified the cheapest property.
The short version
Section titled “The short version”A complete validation answers five separate questions. They are independent — passing one says nothing about the others:
- Integrity — do the signed bytes still hash to what the signature covers? (Recompute the byte-range digest; compare.)
- Authenticity — does the cryptographic signature verify against the public key in the signing certificate, over the signed attributes?
- Certificate path — does that certificate chain to a trust anchor you chose, with every link valid?
- Time — was the certificate within its validity window at the relevant time, and is that time trusted rather than self-asserted?
- Revocation — was the certificate not revoked at that time, by evidence (OCSP/CRL) you can actually obtain or that is embedded?
A “valid” that did not perform all five is an incomplete answer that looks like a complete answer.
How NextPDF approaches it
Section titled “How NextPDF approaches it”NextPDF’s stance is that each question is separate and each must be answered explicitly. A question is never collapsed into one optimistic flag, and never silently skipped because a check was inconvenient. This is enforced by tests. That is why this page is marked test-backed rather than standard-backed: the behavior is held in place by the suite, not only argued from a clause.
Integrity and authenticity are tested end to end. A known certificate signs a real signed-attributes structure, and the suite verifies the signature with the matching public key, across multiple time vectors. So a change that breaks the canonical structure breaks the test. Certificate-path validation is held by tests that deliberately tamper a signature byte and assert the result is not valid with a structured reason — not a discarded exception, but an explicit recorded failure. Timestamp-token verification is broken into discrete steps — decode, signer info, signed attributes, message digest, certificate binding, key usage, signature, produced-at — and each step is tested on its own, so “the timestamp verified” means every step verified. Revocation soft-failure (an unreachable responder) is distinguished, in code and in tests, from a definitive “revoked”. The two are never conflated into the same answer.
- Integrity Recompute the byte-range digest and compare it to the value the signature covers.
- Authenticity Verify the cryptographic signature against the certificate’s public key, over the signed attributes — not the raw content.
- Certificate path Build and validate the chain to a trust anchor you chose; every link’s signature, validity, and constraints must hold.
- Time Confirm the certificate was valid at the relevant instant, and that the instant is trusted time, not the signer’s clock.
- Revocation Confirm the certificate was not revoked at that time, using obtainable or embedded OCSP/CRL evidence.
What the evidence says
Section titled “What the evidence says”Evidence: Test-backed The behavior is anchored by tests, and those tests implement what the standards require.
Integrity is Spec: ISO 32000-2, §12.8.1 ISO 32000-2 §12.8.1 : the digest
is recomputed over the byte range and compared to the stored value, and any
difference means the signature is invalid. Authenticity over the signed
attributes is covered by an integration test that signs a real
signed-attributes set and verifies it with the matching public key across
several time vectors. The certificate-path question is
Spec: RFC 5280, §6.1 RFC 5280 §6.1 : valid paths begin from a trust
anchor, and Spec: RFC 5280, §6.2 RFC 5280 §6.2 states that algorithm
defines the minimum conditions for a path to be valid — a path validator
unit test asserts that a tampered signature yields valid = false with an
explicit reason, never a silent accept.
Revocation ordering is Spec: RFC 6960, §3.2 RFC 6960 §3.2 : before a
client accepts a signed revocation response as valid it SHALL confirm the
response’s own signature is valid and that the signer is currently authorized —
and Spec: RFC 6960, §4.2.2.2 RFC 6960 §4.2.2.2 defines that authorization
as an id-kp-OCSPSigning delegation issued directly by the CA in question. So a
revocation answer that has not itself been validated against an authorized,
verifiable signer is meaningless. The
certificate-binding check is Spec: RFC 5035, §5.4.2 RFC 5035 §5.4.2 : if
the certificate hash in the signed signing-certificate-v2 attribute does not
match the certificate used to verify the signature, the signature must be
considered invalid. This closes the substitution gap, where a signature
verifies against an attacker-chosen certificate. The timestamp’s own token is
verified Spec: RFC 5652 RFC 5652 -style as a CMS object, step by step,
each step tested on its own.
Practical example
Section titled “Practical example”The instructive part is not an API call. It is the questions you must be able to answer before you act on a result. Treat this as the checklist that a review will hold you to.
<?php
declare(strict_types=1);
// A correct validation produces a structured outcome, not one boolean.// Before you trust a signature, you must be able to answer ALL of these://// integrity : Does the byte-range digest still match? (tamper check)// authenticity: Does the signature verify over the SIGNED ATTRIBUTES,// not just the content?// path : Does the certificate chain to a trust anchor YOU chose,// with every link valid at the relevant time?// time : Is the relevant time TRUSTED (a timestamp), or merely the// signer's self-asserted clock?// revocation : Was the certificate not revoked at that time, by evidence// you obtained or that the document embedded?//// "valid: true" without an answer to every line above is an incomplete// result. A path-validation outcome carries a `valid` flag AND a structured// `reasons` list precisely so a failure says WHY — never a bare false.If any line is “I don’t know,” the honest status is not “valid.” It is “not yet determined” — and treating the two as the same is the error this page exists to prevent.
Common misconception
Section titled “Common misconception”The trap is equating “cryptographically valid” with “trustworthy.” Integrity and authenticity together only prove these bytes were signed by the holder of this key. They say nothing about whether the key’s certificate was trusted, current, or unrevoked. A document signed with a self-generated certificate can be “cryptographically valid” and worth nothing. The inverse trap is treating an indeterminate revocation check (responder offline) as a pass — or as a fail. It is neither. It is unknown, and a correct validator reports it as unknown rather than guessing in either direction. A green checkmark that hides which of the five checks actually ran is not a validation result. It is a decision someone else made on your behalf.
Limits and boundaries
Section titled “Limits and boundaries”NextPDF performs and tests the structural and cryptographic checks. It does not choose your trust anchors or guarantee the policy on top of them. Which certificates you trust is a deployment decision the engine cannot make. A chain that validates to an anchor you should not have trusted is still a validation you cannot rely on. Revocation evidence can only be checked if it is obtainable or embedded. An offline responder yields “indeterminate,” and turning that into a verdict is a policy choice, not an engine one. This page describes the check set, not legal sufficiency. Whether a validated signature has a particular legal effect depends on the certificate, the signer, the jurisdiction, and the obligation. How embedded evidence keeps these checks answerable over time is covered in Long-term validation; the byte-range mechanism behind the integrity check is in How signatures sit in a PDF.
Tier availability of the validation surface:
| Edition | Availability |
|---|---|
| Core | Integrity and authenticity over signed attributes, plus RFC 5280 §6 certificate-path validation against a supplied trust anchor. |
| Pro | Adds RFC 3161 timestamp-token verification — the trusted-time question, decomposed into independently checked steps. |
| Enterprise | Adds revocation evaluation (OCSP/CRL) and validation against embedded long-term material, with indeterminate outcomes distinguished from definitive ones. |
Related docs
Section titled “Related docs”- Long-term validation — how embedded evidence keeps the time and revocation checks answerable years later.
- How signatures sit in a PDF — the byte-range mechanism the integrity check recomputes.
- Timestamps and trusted time — what makes the “time” question answerable with something other than the signer’s clock.
Glossary
Section titled “Glossary”- Integrity check — recomputing the byte-range digest and comparing it to the value the signature covers.
- Authenticity check — verifying the cryptographic signature against the signing certificate’s public key, over the signed attributes.
- Signed attributes — the authenticated CMS attributes (content-type, message-digest, signing-time, signing-certificate-v2) the signature is actually computed over.
- Certificate path validation — building and checking the chain from the signing certificate to a chosen trust anchor (RFC 5280 §6).
- Trust anchor — a certificate authority you have decided to trust; the root of an acceptable path.
- Revocation check — determining whether a certificate was revoked at the relevant time, via OCSP or a CRL.
- Indeterminate — a revocation outcome that is neither “good” nor “revoked” because the evidence could not be obtained; not a pass and not a fail.