Table of contents
Namespace: Com\Tecnick\Pdf\Sign\Cms
final class Certificate
Source: src/Cms/Certificate.php:40
Reads the TBSCertificate fields that CMS and OCSP structures quote verbatim: the issuer and subject Names, the serial number, and the public key bits. The raw DER of each field is preserved, because IssuerAndSerialNumber and the OCSP CertID must carry the certificate’s own encoding rather than a re-encoding of the decoded value.
Constants
MAX_EMBEDDED_CERTIFICATES
Most certificates accepted in an unauthenticated CMS CertificateSet.
Ocsp\Client::MAX_RESPONDER_CERTIFICATES and Signer::MAX_PATH_CERTIFICATES read it, so every certificate bag is held to the same bound.
public const MAX_EMBEDDED_CERTIFICATES = 32
Source: src/Cms/Certificate.php:55
Methods
__construct()
public __construct(?Asn1 $asn1 = null)
Parameters:
$asn1(?Asn1)
Source: src/Cms/Certificate.php:97
assertUsableForCrlSigning()
Assert that a certificate may have issued a CRL.
RFC 5280 section 6.3.3 (f) requires the basicConstraints CA flag plus a keyUsage admitting cRLSign (section 4.2.1.3). A certificate without the keyUsage extension is unrestricted for that purpose and passes; one that is not a CA never does.
public assertUsableForCrlSigning(string $certDer): void
Parameters:
$certDer(string)
Throws:
- Exception: If the certificate is not a CA or its key usage forbids cRLSign.
Source: src/Cms/Certificate.php:419
assertUsableForSigning()
Assert that a certificate’s key usage admits signing.
RFC 5280 section 4.2.1.3: a KeyUsage extension that carries neither digitalSignature nor nonRepudiation (contentCommitment) forbids the signature a CAdES SignerInfo carries. A certificate without the extension is unrestricted and passes.
public assertUsableForSigning(string $certDer): void
Parameters:
$certDer(string)
Throws:
- Exception: If the extension is present and admits neither purpose.
Source: src/Cms/Certificate.php:399
assertValidAt()
Assert that a certificate is inside its validity period at a given time.
Not called by Builder, since a host may deliberately re-sign historical content; it is for a host that wants the check before it commits.
public assertValidAt(string $certDer, int $time, int $tolerance = 0): void
Parameters:
$certDer(string)$time(int): Unix time the certificate must cover.$tolerance(int): Clock skew tolerated on either bound, in seconds.
Throws:
- Exception: If the certificate cannot be parsed or does not cover $time.
Source: src/Cms/Certificate.php:376
clearOpenSslErrors()
Discard whatever the last OpenSSL call left in the thread’s error queue.
The queue is process-wide and never drained by PHP, so entries left by a failed verification would surface in the host’s next openssl_error_string().
public static clearOpenSslErrors(): void
Source: src/Cms/Certificate.php:442
deduplicate()
Deduplicate a list of binary blobs by content, preserving first-seen order.
public static deduplicate(list<string> $items): list<string>
Parameters:
$items(list<string>)
Returns: list<string>
Source: src/Cms/Certificate.php:1228
derToPem()
Wrap DER certificate bytes as PEM.
public static derToPem(string $der): string
Parameters:
$der(string)
Returns: string
Source: src/Cms/Certificate.php:1216
encapsulatedContent()
Read the eContentType and the eContent octets of a SignedData.
RFC 5652 section 5.1 puts encapContentInfo third, after version and digestAlgorithms, and section 5.2 shapes it as SEQUENCE { eContentType OBJECT IDENTIFIER, eContent [0] EXPLICIT OCTET STRING OPTIONAL }. Nothing follows either field. The two fields ahead of it are held to the shape assertSignedDataHead() states.
eContent is OPTIONAL and absent in a detached signature, which is what this library emits for a PDF. Under $detached the field has to be absent rather than merely unread.
public encapsulatedContent(string $signedData, int &$offset, bool $detached = false): array{string, string}
Parameters:
$signedData(string)$offset(int): Read cursor; advanced past encapContentInfo.$detached(bool): Expect a signature with no eContent of its own.
Returns: array{string, string}: [complete eContentType OID element, eContent octets, empty when $detached]
Throws:
- Exception: If the content is malformed, or is absent and was expected, or is present and was not.
Source: src/Cms/Certificate.php:763
extendedKeyUsage()
Read a certificate’s extendedKeyUsage purposes.
RFC 5280 section 4.2.1.12: the extension states the purposes the key may be used for, and a purpose that is not listed is one the key may not serve. The purposes are returned as the OIDs the extension names, not as rendered names.
public extendedKeyUsage(string $certDer): list<string>|null
Parameters:
$certDer(string)
Returns: list<string>|null: Purpose OIDs in dotted form, or null when the extension is absent and every purpose is admitted.
Throws:
- Exception: If the certificate or the extension cannot be read.
Source: src/Cms/Certificate.php:464
extendedKeyUsageIsCritical()
True when a certificate’s extendedKeyUsage extension is marked critical.
RFC 3161 section 2.3 requires it of a TSA certificate.
public extendedKeyUsageIsCritical(string $certDer): bool
Parameters:
$certDer(string)
Returns: bool
Throws:
- Exception: If the certificate cannot be read.
Source: src/Cms/Certificate.php:476
extendedKeyUsageWithCriticality()
Read a certificate’s extendedKeyUsage purposes along with its criticality.
Both values are read off one decode, which is what RFC 3161 section 2.3 asks of a TSA certificate.
public extendedKeyUsageWithCriticality(string $certDer): array{list<string>|null, bool}
Parameters:
$certDer(string)
Returns: array{list<string>|null, bool}: [purpose OIDs in dotted form, or null when the extension is absent and every purpose is admitted; whether it is critical]
Throws:
- Exception: If the certificate or the extension cannot be read.
Source: src/Cms/Certificate.php:492
extensions()
The DER is decoded directly rather than through OpenSSL’s rendering, which flattens each extension to a string with no structure left in it.
public extensions(string $certDer): array<string,array{critical: bool, value: string}>
Parameters:
$certDer(string)
Returns: array<string,array{critical: bool, value: string}>: Keyed by extension OID, empty when the certificate carries none.
Throws:
- Exception: If the certificate cannot be parsed.
Source: src/Cms/Certificate.php:135
fields()
Read the quoted TBSCertificate fields of a DER-encoded X.509 certificate.
The serial and Name entries are the complete TLV as the certificate carries them. The public key is the subjectPublicKey BIT STRING value without its leading unused-bits octet, which is what an OCSP issuerKeyHash covers. The validity bounds are Unix times decoded from the Time CHOICE the issuer used.
Every field is tag-checked and the whole structure is walked. The input must be exactly one certificate, with nothing following any of its fields.
public fields(string $certDer): array{serial: string, issuer: string, subject: string, public_key: string, not_before: int, not_after: int}
Parameters:
$certDer(string)
Returns: array{serial: string, issuer: string, subject: string, public_key: string, not_before: int, not_after: int}
Throws:
- Exception: If the certificate cannot be parsed.
Source: src/Cms/Certificate.php:118
fromSignedData()
Extract the X.509 certificates a CMS SignedData embeds.
A CertificateChoices alternative that is not a plain certificate is tagged and skipped, and a member that does not parse as a certificate is dropped, so the result is always a list of DER certificates.
The field sits outside signedAttrs and is covered by no signature, so each member is parsed as a certificate before it is kept.
Under $strict a tagged member is refused along with a SEQUENCE that is not a certificate, and the rest of the SignedData is bounded: the crls [1] field, the signerInfos SET, and the tail. RFC 5652 section 10.2.2 types the field as a set of CertificateChoices.
public fromSignedData(string $cmsDer, bool $strict = false): list<string>
Parameters:
$cmsDer(string)$strict(bool): Refuse any member that is not a certificate, rather than dropping it, and bound the rest of the SignedData.
Returns: list<string>: DER certificates, empty when the CMS embeds none.
Throws:
- Exception: If the CMS cannot be parsed, or $strict and a member is not a certificate.
Source: src/Cms/Certificate.php:827
isCertificateAuthority()
True when a certificate’s basicConstraints marks it as a CA.
RFC 5280 section 4.2.1.9. An absent extension reads as not a CA.
public isCertificateAuthority(string $certDer): bool
Parameters:
$certDer(string)
Returns: bool
Throws:
- Exception: If the certificate or the extension cannot be read.
Source: src/Cms/Certificate.php:536
isIssuerOf()
True when the subject Name of the issuer certificate equals the issuer Name of the subject certificate.
Compares the DER of the two Names, which is the match rule CMS and OCSP apply. It establishes the naming link only, not the signature.
public isIssuerOf(string $issuerDer, string $subjectDer): bool
Parameters:
$issuerDer(string)$subjectDer(string)
Returns: bool
Throws:
- Exception: If either certificate cannot be parsed.
Source: src/Cms/Certificate.php:700
pemToDer()
Decode a PEM certificate to DER.
Exactly one certificate is decoded; a file holding more than one, such as a fullchain.pem, is refused. The armour has to say CERTIFICATE, and the decoded bytes have to parse as one. A body with no armour is accepted as base64 and held to the same parse.
public static pemToDer(string $pem): string
Parameters:
$pem(string)
Returns: string
Throws:
- Exception: If the PEM holds no certificate, more than one, or something that is not one.
Source: src/Cms/Certificate.php:1160
signatureTimestampTokens()
Extract the RFC 3161 tokens a CMS carries as signature timestamps.
Reads the id-aa-signatureTimeStampToken unsigned attribute of each SignerInfo (CAdES, ETSI EN 319 122-1 section 5.3), which sign() embeds for a PAdES B-T signature and Signer::collectValidationMaterial() takes as input.
unsignedAttrs sits outside the signature, so a member that cannot be read as a CMS SignedData is passed over rather than returned or thrown on.
public signatureTimestampTokens(string $cmsDer): list<string>
Parameters:
$cmsDer(string)
Returns: list<string>: DER tokens, empty when the CMS carries none.
Throws:
- Exception: If the CMS cannot be parsed.
Source: src/Cms/Certificate.php:970
signedDataContent()
Unwrap a CMS ContentInfo to the content octets of its SignedData.
The input must be exactly one ContentInfo, and each layer of it exactly one element, with no trailing bytes.
public signedDataContent(string $cmsDer): string
Parameters:
$cmsDer(string)
Returns: string
Throws:
- Exception: If the input is not a CMS SignedData.
Source: src/Cms/Certificate.php:713
signerInfos()
Read the content octets of each SignerInfo of a SignedData.
RFC 5652 section 5.1 puts certificates [0] and crls [1] between encapContentInfo and signerInfos, each OPTIONAL, each admissible once, and in that order. Nothing may follow signerInfos.
public signerInfos(string $signedData, int $offset): list<string>
Parameters:
$signedData(string)$offset(int): Read cursor positioned just after encapContentInfo.
Returns: list<string>: SignerInfo content octets, one per member of the SET.
Throws:
- Exception: If the structure is malformed or carries no SignerInfo.
Source: src/Cms/Certificate.php:1058
subjectKeyIdentifier()
Read a certificate’s subjectKeyIdentifier.
RFC 5280 section 4.2.1.2 shapes the extension value as KeyIdentifier ::= OCTET STRING. It is what a CMS SignerIdentifier names when it does not name an IssuerAndSerialNumber.
public subjectKeyIdentifier(string $certDer): string
Parameters:
$certDer(string)
Returns: string: Raw identifier octets, or ’’ when the extension is absent or cannot be read, which can never equal a non-empty identifier.
Source: src/Cms/Certificate.php:551
toDer()
Decode a certificate given as either PEM or DER. Both encodings are parsed.
A DER certificate begins with the SEQUENCE tag 0x30 and a long-form length, whose first octet has the high bit set. A PEM body cannot: it is ASCII, so its second octet is always below 0x80.
public static toDer(string $certificate): string
Parameters:
$certificate(string)
Returns: string
Throws:
- Exception: If the value is neither a PEM nor a DER certificate.
Source: src/Cms/Certificate.php:1202