Skip to content

Signer expiration shows "No expiration date" although notAfter is present in the embedded certificate chain #7825

Description

@konradbr

Describe the bug

On the document validation panel every signer shows "Expiration: No expiration date", even though the signer's leaf certificate carries a valid notAfter.

To reproduce

  1. Configure LibreSign with the OpenSSL engine and a self-hosted root CA; set a leaf validity (e.g. 1460 days).
  2. Sign any PDF (click-to-sign or certificate-with-password — both reproduce).
  3. Open the document's validation panel.
  4. Look at the signer's Expiration line → it reads "No expiration date".

Expected behavior

The Expiration line should show the leaf certificate's notAfter (e.g. 21 Jun 2030), which is present in the embedded chain.

Screenshots

Image

Operational System

Linux

Browser Type and Version

Firefox

Libresign Version

14.0.1

Nextcloud Server Version

34

Logs from Nextcloud Server

Not released.

Logs from Developers tools

No response

Additional context

Evidence — notAfter is present in the signed PDF. From a JSignPdf-signed PDF (SHA-512); each
signature embeds the full chain (root + leaf):

$ pdfsig signed.pdf
Signature #1:
  - Signer Certificate Common Name: {{ signer_cn }}
  - Signing Time: {{ signing_time }}
  - Signing Hash Algorithm: SHA-512
  - Signature Type: adbe.pkcs7.detached
  - Signature Validation: Signature is Valid.
  - Certificate Validation: Certificate issuer isn't Trusted.   # private CA -> caution shield (expected, out of scope)

$ openssl pkcs7 -inform DER -in <embedded-sig> -print_certs | openssl x509 -noout -subject -dates
# leaf:
subject= ... CN = {{ signer_cn }}
notBefore={{ leaf_not_before }}
notAfter ={{ leaf_not_after }}      <-- present, but panel shows "No expiration date"
# root:
subject= ... CN = {{ root_ca_cn }}
notAfter ={{ root_not_after }}

Ruled out:

  • Not the certificate — leaf carries notAfter; CRL Management lists signers as ISSUED with the correct expiry.
  • Not the signing method — click-to-sign and certificate-with-password both blank.
  • Not the request "Maximum validity" setting — blank either way.
  • Not the signature engine — blank on both Native (signer-php) and JSignPdf.

Possible lead (for maintainers). PR #5816 ("feat: check the certificate expiration date", in 14.x)
parses a valid_to field with the locale-dependent format 'F j, Y, g:i:s A':

$validTo = \DateTime::createFromFormat('F j, Y, g:i:s A', $certificateData['valid_to']);

If the read-back that feeds the validation panel populates / parses valid_to the same way, a missing or
differently-formatted valid_to would render as "No expiration date". (We hit a related locale issue on this
host — Java/PHP LANG — so a locale-sensitive date parse is plausible.) Please confirm against current source.

Out of scope. The caution shield is the expected indicator for a self-hosted private CA whose root is not
in public trust stores (pdfsig: "Certificate issuer isn't Trusted") — separate from this expiration-display bug.

Workaround. None in the UI; expiry is verifiable out-of-band with openssl x509 / pdfsig.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Fields

    No fields configured for Bug.

    Projects

    Status
    0. Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions