generated from jric11/baseProject
175 lines
5.4 KiB
PHP
175 lines
5.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Config.php
|
||
|
|
*
|
||
|
|
* @since 2026-07-15
|
||
|
|
* @category Library
|
||
|
|
* @package PdfSign
|
||
|
|
* @author Nicola Asuni <info@tecnick.com>
|
||
|
|
* @copyright 2026 Nicola Asuni - Tecnick.com LTD
|
||
|
|
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
|
||
|
|
* @link https://github.com/tecnickcom/tc-lib-pdf-sign
|
||
|
|
*
|
||
|
|
* This file is part of tc-lib-pdf-sign software library.
|
||
|
|
*/
|
||
|
|
|
||
|
|
namespace Com\Tecnick\Pdf\Sign;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Com\Tecnick\Pdf\Sign\Config
|
||
|
|
*
|
||
|
|
* Immutable signature configuration value object. Captures the signing profile,
|
||
|
|
* digest algorithm, and certification level, and derives the PDF /SubFilter
|
||
|
|
* from the selected profile.
|
||
|
|
*
|
||
|
|
* @since 2026-07-15
|
||
|
|
* @category Library
|
||
|
|
* @package PdfSign
|
||
|
|
* @author Nicola Asuni <info@tecnick.com>
|
||
|
|
* @copyright 2026 Nicola Asuni - Tecnick.com LTD
|
||
|
|
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
|
||
|
|
* @link https://github.com/tecnickcom/tc-lib-pdf-sign
|
||
|
|
*/
|
||
|
|
final class Config
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Legacy ISO 32000-1 signature (/SubFilter /adbe.pkcs7.detached).
|
||
|
|
*/
|
||
|
|
public const PROFILE_LEGACY = 'legacy';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PAdES baseline B-B (CAdES-based, /SubFilter /ETSI.CAdES.detached).
|
||
|
|
*/
|
||
|
|
public const PROFILE_PADES_B_B = 'pades-b-b';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PAdES baseline B-T (B-B plus a signature timestamp).
|
||
|
|
*/
|
||
|
|
public const PROFILE_PADES_B_T = 'pades-b-t';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PAdES baseline B-LT (B-T plus a Document Security Store).
|
||
|
|
*/
|
||
|
|
public const PROFILE_PADES_B_LT = 'pades-b-lt';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PAdES baseline B-LTA (B-LT plus a document timestamp).
|
||
|
|
*/
|
||
|
|
public const PROFILE_PADES_B_LTA = 'pades-b-lta';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Supported signature profiles.
|
||
|
|
*
|
||
|
|
* @var list<string>
|
||
|
|
*/
|
||
|
|
public const PROFILES = [
|
||
|
|
self::PROFILE_LEGACY,
|
||
|
|
self::PROFILE_PADES_B_B,
|
||
|
|
self::PROFILE_PADES_B_T,
|
||
|
|
self::PROFILE_PADES_B_LT,
|
||
|
|
self::PROFILE_PADES_B_LTA,
|
||
|
|
];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Supported CMS digest algorithms.
|
||
|
|
*
|
||
|
|
* @var list<string>
|
||
|
|
*/
|
||
|
|
public const DIGEST_ALGORITHMS = ['sha256', 'sha384', 'sha512'];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Selected signature profile (one of the PROFILE_* constants).
|
||
|
|
*/
|
||
|
|
public readonly string $profile;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Selected CMS digest algorithm (one of the DIGEST_ALGORITHMS values).
|
||
|
|
*/
|
||
|
|
public readonly string $digestAlgorithm;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string|SignatureProfile $profile Profile identifier or enum case.
|
||
|
|
* @param string|DigestAlgorithm $digestAlgorithm Digest algorithm name or enum case.
|
||
|
|
* @param int $certType Certification level (DocMDP P value):
|
||
|
|
* 0 = approval/UR signature,
|
||
|
|
* 1 = no changes permitted,
|
||
|
|
* 2 = form fill-in and signing permitted,
|
||
|
|
* 3 = as 2 plus annotation changes.
|
||
|
|
*
|
||
|
|
* @throws Exception If any option is invalid.
|
||
|
|
*/
|
||
|
|
public function __construct(
|
||
|
|
string|SignatureProfile $profile = self::PROFILE_LEGACY,
|
||
|
|
string|DigestAlgorithm $digestAlgorithm = 'sha256',
|
||
|
|
public readonly int $certType = 2,
|
||
|
|
) {
|
||
|
|
$profile = $profile instanceof SignatureProfile ? $profile->value : $profile;
|
||
|
|
$digestAlgorithm = $digestAlgorithm instanceof DigestAlgorithm ? $digestAlgorithm->value : $digestAlgorithm;
|
||
|
|
|
||
|
|
if (!\in_array($profile, self::PROFILES, true)) {
|
||
|
|
throw new Exception('Invalid signature profile: ' . $profile);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!\in_array($digestAlgorithm, self::DIGEST_ALGORITHMS, true)) {
|
||
|
|
throw new Exception('Invalid digest algorithm: ' . $digestAlgorithm);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($certType < 0 || $certType > 3) {
|
||
|
|
throw new Exception('Invalid certification level (cert_type): ' . $certType);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->profile = $profile;
|
||
|
|
$this->digestAlgorithm = $digestAlgorithm;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* True when a PAdES profile is selected.
|
||
|
|
*/
|
||
|
|
public function isPades(): bool
|
||
|
|
{
|
||
|
|
return $this->profile !== self::PROFILE_LEGACY;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PDF /SubFilter value for the selected profile.
|
||
|
|
*/
|
||
|
|
public function subFilter(): string
|
||
|
|
{
|
||
|
|
return $this->isPades() ? 'ETSI.CAdES.detached' : 'adbe.pkcs7.detached';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Build a Config from the legacy associative-array shape used by
|
||
|
|
* Tcpdf::setSignature(), for backward compatibility.
|
||
|
|
*
|
||
|
|
* @param array<string, mixed> $data Signature options.
|
||
|
|
*
|
||
|
|
* @throws Exception If any option is present but of the wrong type or value.
|
||
|
|
*/
|
||
|
|
public static function fromArray(array $data): self
|
||
|
|
{
|
||
|
|
/** @var mixed $profile */
|
||
|
|
$profile = $data['profile'] ?? self::PROFILE_LEGACY;
|
||
|
|
if (!\is_string($profile) && !$profile instanceof SignatureProfile) {
|
||
|
|
throw new Exception('Invalid signature profile');
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @var mixed $digest */
|
||
|
|
$digest = $data['digest_algorithm'] ?? 'sha256';
|
||
|
|
if (!\is_string($digest) && !$digest instanceof DigestAlgorithm) {
|
||
|
|
throw new Exception('Invalid digest algorithm');
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @var mixed $certType */
|
||
|
|
$certType = $data['cert_type'] ?? 2;
|
||
|
|
if (!\is_int($certType)) {
|
||
|
|
throw new Exception('Invalid certification level (cert_type)');
|
||
|
|
}
|
||
|
|
|
||
|
|
return new self($profile, $digest, $certType);
|
||
|
|
}
|
||
|
|
}
|