Signer

Package-internal orchestration entry point that ties the CMS builder, the RFC 3161 timestamp codec, and the LTV material collector together behind two host-facing calls. It stays transport-injected and free of file and network access: the host loads keys and owns HTTP (and SSRF protection).

Namespace: Com\Tecnick\Pdf\Sign

Final: Yes

File: Signer.php line 60

Package-internal orchestration entry point that ties the CMS builder, the RFC 3161 timestamp codec, and the LTV material collector together behind two host-facing calls. It stays transport-injected and free of file and network access: the host loads keys and owns HTTP (and SSRF protection).

sign() produces the detached CAdES CMS for a document’s ByteRange bytes. For a legacy or PAdES B-B profile that is the plain CMS; for B-T and above it also requests an RFC 3161 signature timestamp and embeds it as the SignerInfo id-aa-signatureTimeStampToken unsigned attribute.

prepare() and buildFromSignature() are the same call split in two, for a signature made outside this process. They apply the same profile rules as sign().

collectValidationMaterial() gathers the certificates, OCSP responses, and CRLs a B-LT or B-LTA document needs, shaped for the DSS emitter. The VRI key is not computed here: it depends on the final signature Contents and belongs to the DSS writer.

Tags

Constants

MAX_PATH_CERTIFICATES

File: Signer.php line 78

public mixed MAX_PATH_CERTIFICATES = \Com\Tecnick\Pdf\Sign\Cms\Certificate::MAX_EMBEDDED_CERTIFICATES

Methods

__construct()

File: Signer.php line 106

public __construct([Builder|null $builder = null ][, ValidationMaterial|null $validationMaterial = null ][, Certificate|null $certificate = null ][, bool $checkSignerCertificate = false ][, SignedDataVerifier|null $tokenVerifier = null ]) : mixed

Parameters

  • $builder : Builder|null = null
  • $validationMaterial : ValidationMaterial|null = null
  • $certificate : Certificate|null = null
  • $checkSignerCertificate : bool = false: Refuse to sign with a certificate that had expired, was not yet valid, or whose key usage forbids signing. Off by default, since a host may deliberately re-sign historical content.
  • $tokenVerifier : SignedDataVerifier|null = null: Resolves the signer certificate of a timestamp token passed to collectValidationMaterial(). The default one requires the ESS signing-certificate attribute RFC 3161 section 2.4.2 asks of a token. Pass one constructed with $allowSha1 to accept a token from a responder that signs with nothing else, or without $requireSigningCertificate for a TSA that emits no such attribute.

Tags

  • throws: Exception If a default collaborator cannot be constructed.

buildFromSignature()

File: Signer.php line 257

public buildFromSignature(SigningRequest $request, string $signature, array<int, string> $chainCertsDer, Config $config[, Client|null $timestamp = null ][, callable(string): string|null $timestampTransport = null ][, string|SignatureEncoding $signatureEncoding = SignatureEncoding::Der ][, int|null $timestampNow = null ]) : string

The second half of sign(). As there, a B-T or higher profile requires the timestamp client and transport, and the RFC 3161 token is requested over the raw signature bytes.

Parameters

  • $request : SigningRequest: The request returned by prepare().
  • $signature : string: Signature over Cms\Builder::signaturePayload($request).
  • $chainCertsDer : array<int, string>: Additional certificates to embed, each as PEM or as DER.
  • $config : Config: Signature profile and digest configuration.
  • $timestamp : Client|null = null: RFC 3161 codec; required for B-T and above.
  • $timestampTransport : callable(string): string|null = null: Maps a DER TimeStampReq to a DER TimeStampResp; required for B-T and above.
  • $signatureEncoding : string|SignatureEncoding = SignatureEncoding::Der: Encoding of $signature.
  • $timestampNow : int|null = null: Unix time the token’s genTime is checked against; defaults to the current time.

Tags

  • throws: Exception If the request was prepared under another configuration, a timestamp is required but not configured, the signing certificate fails the optional checks, or the signature does not verify.

Return values

string —

DER-encoded CMS ContentInfo ready for /Contents injection.

collectValidationMaterial()

File: Signer.php line 424

public collectValidationMaterial(array<int, string> $chainPem[, callable(string, string): Array|null $ocspTransport = null ][, callable(string): Array|null $crlTransport = null ][, array<int, string> $timestampTokens = [] ][, int|null $now = null ][, callable(string, string, string, SkipReason): void|null $onSkip = null ]) : array{certs: list, ocsp: list, crls: list}

The chain must be ordered leaf-first, each entry followed by its issuer, and the ordering is verified by signature. For every certificate that has an issuer in the chain, OCSP and CRL lookups are attempted against the responder URLs in its AIA extension and the distribution points it names. A certificate with no issuer in the chain gets neither, and every URL skipped for that reason is reported through $onSkip with the NotAttempted code; a self-signed root is not reported. A null transport skips that revocation source. Responses are deduplicated across the whole chain.

A certificate either source reported revoked contributes no material at all, not even the other source’s. The certificate itself stays in the result, and the verdict reaches the caller through $onSkip with the Revoked code.

Each token in $timestampTokens is verified, its embedded TSA certificates are ordered into a path starting at the certificate that signed it, and that path is collected alongside the signer’s chain with the same lookups, as ETSI EN 319 142-1 requires of a B-LT Document Security Store. A bag member outside that path is embedded but not looked up, and its URLs are reported through $onSkip.

Parameters

  • $chainPem : array<int, string>: Certificates leaf first up to the root, each as PEM or as DER.
  • $ocspTransport : callable(string, string): Array|null = null: Maps (url, DER request) to the DER response, or null to skip OCSP.
  • $crlTransport : callable(string): Array|null = null: Maps a url to the CRL bytes, or null to skip CRLs.
  • $timestampTokens : array<int, string> = []: DER timestamp tokens whose embedded certificates are added to the material, along with revocation data for the paths they carry.
  • $now : int|null = null: Unix time the responses are checked against; defaults to the current time. Pass the signing time so a retried or queued signature collects against the same instant it signs for.
  • $onSkip : callable(string, string, string, SkipReason): void|null = null: Receives (source, url, reason, code) for every revocation URL whose answer was discarded or never fetched. The code separates a revoked verdict from an unreachable responder.

Tags

  • throws: Exception If a certificate or a token is not a string, a certificate cannot be parsed, the chain is not ordered leaf-first with each entry followed by its issuer, a token does not verify against a certificate it embeds, or a token embeds more than MAX_PATH_CERTIFICATES certificates.

Return values

array{certs: list, ocsp: list, crls: list} —

DSS-ready material.

prepare()

File: Signer.php line 197

public prepare(string $messageDigest, string $signerCertDer, Config $config, int $signingTime[, array<string|int, string> $extraSignedAttributes = [] ]) : SigningRequest

The first half of sign(), for a private key this process cannot reach. The digest is of the ByteRange-covered document bytes.

Pass the returned request to Cms\Builder::signaturePayload() for the bytes to sign, then back to buildFromSignature() with the signature. Its toArray()/fromArray() pair carries it across a session or a queue.

Parameters

  • $messageDigest : string: Digest of the ByteRange content, raw bytes, computed with the profile’s digest algorithm.
  • $signerCertDer : string: DER of the signing certificate.
  • $config : Config: Signature profile and digest configuration.
  • $signingTime : int: Unix timestamp for the signing-time attribute.
  • $extraSignedAttributes : array<string|int, string> = []: Additional signed attributes as OID => DER-encoded attribute value.

Tags

  • throws: Exception If the digest, the certificate, or an extra attribute is invalid, or the signing certificate fails the optional checks.

Return values

SigningRequest

sign()

File: Signer.php line 147

public sign(string $content, string $signerCertDer, OpenSSLAsymmetricKey $privateKey, array<int, string> $chainCertsDer, Config $config, int $signingTime[, Client|null $timestamp = null ][, callable(string): string|null $timestampTransport = null ][, array<string|int, string> $extraSignedAttributes = [] ][, int|null $timestampNow = null ]) : string

When the profile is B-T or above, the timestamp client and transport are required: the RFC 3161 token is requested over the raw signature bytes and embedded as the id-aa-signatureTimeStampToken unsigned attribute.

Parameters

  • $content : string: ByteRange-covered document bytes to sign.
  • $signerCertDer : string: DER of the signing certificate.
  • $privateKey : OpenSSLAsymmetricKey: Signing private key (RSA or EC).
  • $chainCertsDer : array<int, string>: Additional certificates to embed, each as PEM or as DER. Every entry is parsed.
  • $config : Config: Signature profile and digest configuration.
  • $signingTime : int: Unix timestamp for the signing-time attribute.
  • $timestamp : Client|null = null: RFC 3161 codec; required for B-T and above.
  • $timestampTransport : callable(string): string|null = null: Maps a DER TimeStampReq to a DER TimeStampResp; required for B-T and above.
  • $extraSignedAttributes : array<string|int, string> = []: Additional signed attributes as OID => DER-encoded attribute value, as prepare() accepts.
  • $timestampNow : int|null = null: Unix time the token’s genTime is checked against; defaults to the current time. It is the moment the request is made, not the signing time.

Tags

  • throws: Exception If a timestamp is required but not configured, signing fails, or the signing certificate fails the optional checks.

Return values

string —

DER-encoded CMS ContentInfo ready for /Contents injection.

signaturePayload()

File: Signer.php line 227

public signaturePayload(SigningRequest $request) : string

A passthrough to Cms\Builder::signaturePayload().

Parameters

Tags

  • throws: Exception If the digest is unsupported or encoding fails.

Return values

string —

DER SET OF signed attributes, ready to be signed.

signatureTimestampTokens()

File: Signer.php line 371

public signatureTimestampTokens(string $cmsDer) : array<int, string>

Returns the tokens sign() and buildFromSignature() embed as the id-aa-signatureTimeStampToken unsigned attribute, which is what collectValidationMaterial() takes as its fourth argument.

Parameters

  • $cmsDer : string: The CMS returned by sign() or buildFromSignature().

Tags

  • throws: Exception If the CMS cannot be parsed.

Return values

array<int, string> —

DER tokens, empty for a B-B or legacy signature.