ข้ามไปยังเนื้อหา
getnextpdf.com

Enterprise รุ่น

Trusted lists — เอกสารอ้างอิงเชิงลึก

หน้านี้คือการอ้างอิงเชิงลึกสำหรับพื้นผิว trusted-list ใน NextPDF Enterprise พื้นผิวนี้คือคลาสสาธารณะสิบสองคลาสของเนมสเปซ NextPDF\Enterprise\Security\Tsl โดย NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer เป็นจุดเข้าที่ถูกจัดวางไว้: มันจะคืน TslDocument เฉพาะเมื่อการ fetch ผ่าน HTTP, การตรวจ XMLDSig, การ parse เชิงโครงสร้าง และเกตความล้าสมัย nextUpdate ผ่านทั้งหมด จากนั้น TslTrustAnchorProvider::buildBundle() จะอนุมานชุด trust-anchor จากบริการ CA/QC ที่ยังใช้งานอยู่ โดยยืนยัน freshness อีกครั้ง ณ ช่วงเวลาที่ผู้เรียกกำหนด ก่อนที่จะดึง anchor ใด ๆ ทุกความล้มเหลวจะยกข้อยกเว้นที่มีชนิดกำกับ ไม่มีขั้นตอนใดเสื่อมสภาพอย่างเงียบ ๆ ไปป์ไลน์รองรับการตรวจ trusted list ของรัฐสมาชิก EU และ trust anchor ที่มาจาก LOTL (List of Trusted Lists) เมื่อผู้เรียกจัดหามาให้ ส่วนการค้นพบ LOTL อัตโนมัติ การ polling และการประมวลผล pivot อยู่นอกขอบเขต

ความสามารถนี้มาพร้อมกับ NextPDF Enterprise (nextpdf/enterprise) และเปิดใช้งานด้วยซองใบอนุญาตระดับ Enterprise การติดตั้งที่ไม่มีสิทธิ์ดังกล่าวจะไม่โหลดคลาสของความสามารถนี้ เปรียบเทียบรุ่นและรับใบอนุญาต

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
TslPolicyEnforcerTslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parserรวม fetch, signature-verify, parse และเกตความล้าสมัยเข้าเป็นจุดเข้าเดียวส่งต่อข้อยกเว้นของไปป์ไลน์ด้านล่างfinal; fail-closed โดยการออกแบบ
TslPolicyEnforcer::fetchAndVerifystring $urlดึง TSL หนึ่งรายการ จากนั้นรัน verifyXml() บนไบต์TslDocumentTslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseExceptionคืนค่าเฉพาะเมื่อทั้งสี่ขั้นตอนผ่าน
TslPolicyEnforcer::verifyXmlstring $xmlตรวจลายเซ็น, parse และปฏิเสธรายการที่ล้าสมัยTslDocumentTslSignatureException, TslParseExceptionความล้าสมัยถูกประเมินเทียบกับเวลาระบบปัจจุบัน
TslFetcherClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINEการดึง TSL/LOTL แบบ HTTPS-only พร้อมแคชอิง ETagfinal; SSRF guard ปิดกั้นโฮสต์ private, loopback, link-local และ metadata พร้อมการบรรเทา DNS-rebinding
TslFetcher::fetchstring $urlGET พร้อม If-None-Match revalidation; แคชเนื้อหาพร้อม ETag ภายใต้ TTL ที่กำหนดstring (raw XML bytes)TslFetchException, NetworkPolicyViolationอ่านได้มากที่สุด $maxBytes ไบต์; ภายใต้ STRICT_OFFLINE จะเสิร์ฟเฉพาะเนื้อหาที่แคชไว้
TslSignatureVerifierarray $trustAnchorsPem, int $clockTolerance = 0ตัวตรวจ XMLDSig ที่ตรึงกับ trust anchor ที่กำหนดInvalidArgumentException เมื่อรายการ anchor ว่างเปล่าfinal; allowlist ใน ALLOWED_SIG_ALG และ ALLOWED_DIGEST_ALG
TslSignatureVerifier::verifystring $xmlตรวจลายเซ็น XMLDSig แบบ enveloped ในโหมด fail-closedstring (signer-certificate PEM)TslSignatureException พร้อม reason code ที่เครื่องอ่านได้ใบรับรองใน KeyInfo ไม่เคยได้รับความเชื่อถือด้วยตัวมันเอง; ผู้ลงนามต้องเชื่อมโยงไปยัง anchor ที่กำหนด
TslXmlParser::parsestring $xmlparse เชิงโครงสร้างเป็น TslDocument; ไม่ขึ้นกับลายเซ็นTslDocumentTslParseExceptionปฏิเสธ DOCTYPE ใด ๆ แบบ fail-closed ก่อน parse; โหลดด้วย LIBXML_NONET; ผู้เรียกต้องตรวจก่อนเชื่อถือผลลัพธ์
TslTrustAnchorProvider::buildBundleTslDocument $tsl, DateTimeImmutable $nowยืนยัน freshness ก่อน แล้วจึงเก็บใบรับรองของบริการ CA/QC ที่ยังใช้งานอยู่EnterpriseCaTrustAnchorBundleTslParseExceptionเกต freshness มาก่อนการดึง anchor ใด ๆ; เซ็ตผลลัพธ์ว่างจะ throw
TslDocumentคุณสมบัติ readonly ที่โปรโมตแปดตัว (ดู constructor fence)ออบเจ็กต์ค่า TSL ที่ parse แล้วแบบ immutablefinal readonly; annotate @api ที่ต้นทาง
TslDocument::isStaleDateTimeImmutable $nowเทียบ nextUpdate กับ $now หลังจาก parse UTC แบบ fail-closedboolTslParseExceptionต้องมี designator Z หรือ numeric-offset อย่างชัดเจน
TslDocument::assertFreshDateTimeImmutable $nowthrow เมื่อรายการล้าสมัยหรือ nextUpdate parse ไม่ได้voidTslParseExceptionเกต freshness ที่ขอบเขตผู้บริโภค
TslDocument::servicesOfTypestring $serviceTypeIdentifierกรองบริการตาม ETSI service-type URIlist<TspService>ไม่ throw
TslDocument::activeServicesคืนเฉพาะบริการที่มีสถานะ grantedlist<TspService>ไม่ throwGranted หมายถึง TspService::STATUS_GRANTED
TspServiceคุณสมบัติ readonly ที่โปรโมตแปดตัวรายการ trust-service หนึ่งรายการภายใน TSLfinal readonly; ค่าคงที่สำหรับ status และ service-type URI
TspService::isGrantedเทียบสถานะเท่ากับ granted URIboolไม่ throw
TspService::isQualifiedCaเทียบชนิดเท่ากับ CA/QC URIboolไม่ throw
TspServiceQualifierstring $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = []qualifier ของบริการ ETSI หนึ่งรายการพร้อมเกณฑ์เสริมfinal readonly; ค่าคงที่ FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD
EnterpriseCaTrustAnchorBundlearray $anchorsPem, string $bundleVersion, string $bundleSha256ชุด anchor ที่ตรึงไว้; ตรวจสอบ digest ที่ให้มากับ anchor ที่ให้มา ณ ตอนสร้างInvalidArgumentExceptionรับมาจาก buildBundle(); อย่าสร้างด้วยมือ; implement TrustAnchorStoreInterface
EnterpriseCaTrustAnchorBundle::containsFingerprintstring $anchorDerSha256Hexสมาชิกภาพของ anchor ด้วย hex SHA-256 เหนือ DER bodyboolไม่ throw
EnterpriseCaTrustAnchorBundle::computeBundleSha256array $anchorsPemSHA-256 เชิงบัญญัติเหนือการต่อ PEM ที่นอร์มัลไลซ์บรรทัดใหม่stringไม่ throwstatic
TslFetchExceptionส่งสัญญาณว่าการดึง TSL ล้มเหลวfinal; สืบทอด RuntimeException
TslParseExceptionส่งสัญญาณความล้มเหลวเชิงโครงสร้างหรือ freshnessfinal; สืบทอด RuntimeException
TslSignatureExceptionstring $reason, string $messageส่งสัญญาณความล้มเหลวในการตรวจ XMLDSig พร้อม reason codefinal; $reason แบบ readonly สาธารณะ (ดู reason codes ด้านล่าง)

TslPolicyEnforcer

public function fetchAndVerify(string $url): TslDocument
public function verifyXml(string $xml): TslDocument

TslFetcher

public function __construct(
private readonly ClientInterface $httpClient,
private readonly RequestFactoryInterface $requestFactory,
private readonly ?CacheInterface $cache = null,
private readonly int $defaultTtlSeconds = 3600,
private readonly int $maxBytes = 16_777_216,
private readonly NetworkPolicy $networkPolicy = NetworkPolicy::ONLINE,
) {}
public function fetch(string $url): string

TslSignatureVerifier

public function __construct(private readonly array $trustAnchorsPem, private readonly int $clockTolerance = 0)
public function verify(string $xml): string

TslXmlParser

public function parse(string $xml): TslDocument

TslTrustAnchorProvider

public function buildBundle(TslDocument $tsl, DateTimeImmutable $now): EnterpriseCaTrustAnchorBundle

TslDocument

public function __construct(
public string $schemeTerritory,
public string $schemeOperatorName,
public string $tslType,
public int $sequenceNumber,
public string $issueDateTime,
public string $nextUpdate,
public array $tspServices,
public string $rawXmlSha256,
) {}
public function isStale(DateTimeImmutable $now): bool
public function assertFresh(DateTimeImmutable $now): void
public function servicesOfType(string $serviceTypeIdentifier): array
public function activeServices(): array

TspService

public function __construct(public string $tspName, public string $serviceName, public string $serviceTypeIdentifier, public string $serviceStatus, public string $statusStartingTime, public string $serviceCertificatePem, public array $qualifiers, public array $additionalServiceInformation) {}
public function isGranted(): bool
public function isQualifiedCa(): bool

TspServiceQualifier

public function __construct(public string $qualifierUri, public string $criteriaListAssert = 'all', public array $policyOidConditions = [], public array $keyUsageConditions = []) {}

EnterpriseCaTrustAnchorBundle

public function __construct(public array $anchorsPem, public string $bundleVersion, public string $bundleSha256)
public function containsFingerprint(string $anchorDerSha256Hex): bool
public static function computeBundleSha256(array $anchorsPem): string

TslSignatureException

public function __construct(public readonly string $reason, string $message)

reason codes ของ TslSignatureException: missing_signature, untrusted_signer, invalid_signature, digest_mismatch, unsupported_algorithm, unsupported_transform, expired_anchor

  • ลำดับของไปป์ไลน์ถูกกำหนดตายตัว: fetch, การตรวจ XMLDSig, การ parse เชิงโครงสร้าง, เกตความล้าสมัย โดย TslPolicyEnforcer จะคืน TslDocument เฉพาะเมื่อทั้งสี่ขั้นตอนสำเร็จ trusted list ถูกลงนามโดยผู้ดำเนินการสคีมเพื่อให้ฝ่ายที่เชื่อถือได้ตรวจสอบความแท้จริงและความสมบูรณ์ — ETSI TS 119 612 §5.7.1
  • TslXmlParser ไม่ขึ้นกับลายเซ็นโดยการออกแบบ ผู้เรียกต้องตรวจลายเซ็นก่อนเชื่อถือฟิลด์ที่ parse แล้วใด ๆ โดย TslPolicyEnforcer::verifyXml() บังคับลำดับนั้น
  • ค่าคงที่ freshness ถูกบังคับใช้ที่ทุกขอบเขตผู้บริโภค รายการที่ nextUpdate ผ่านไปแล้วถือว่าหมดอายุและถูกปฏิเสธ — ETSI TS 119 612 §5.3.15 โดย verifyXml() เกตเทียบกับเวลาระบบปัจจุบัน; ส่วน TslDocument::assertFresh() และ buildBundle() เกตเทียบกับช่วงเวลาที่ผู้เรียกกำหนด
  • การ parse freshness เป็นแบบ fail-closed ฟิลด์วันที่และเวลาเป็นค่า ISO 8601 UTC ที่มี designator อย่างชัดเจน — ETSI TS 119 612 §5.1.3 ค่า nextUpdate ที่ไม่มี Z หรือ numeric offset อย่างชัดเจนจะยก TslParseException; ค่านี้ไม่เคยถูกตีความใหม่ในเขตเวลาท้องถิ่นของเซิร์ฟเวอร์
  • buildBundle() เรียก assertFresh($now) ก่อนดึง anchor ใด ๆ จากนั้นยอมรับเฉพาะบริการที่เป็นทั้ง granted และ CA/QC granted และ withdrawn คือ status URI ของบริการที่ผ่านการรับรอง — ETSI TS 119 612 §5.5.4 CA/QC คือ service-type URI ของ CA ที่ผ่านการรับรอง — ETSI TS 119 612 §5.5.1.1
  • เวอร์ชันของชุดอนุมานจาก scheme territory และ TSL sequence number sequence number เป็นแบบ monotonic ข้ามรุ่นต่าง ๆ — ETSI TS 119 612 §5.3.2 digest ของชุดเป็น SHA-256 เชิงบัญญัติเหนือ PEM ของ anchor และ containsFingerprint() ตอบสมาชิกภาพด้วย DER SHA-256
  • ตัวตรวจเชื่อถือเฉพาะ anchor ที่กำหนดเท่านั้น ใบรับรองที่พบใน KeyInfo ทำหน้าที่เป็น signer leaf และ intermediate ที่เป็นตัวเลือก; ห่วงโซ่ต้องไปถึง anchor ที่กำหนดภายในความลึก 8, ทุกลิงก์ต้องมีความถูกต้องเชิงเวลา และใบรับรองที่ออกให้ต้องมี basicConstraints cA=TRUE (บวก keyCertSign เมื่อมี keyUsage)
  • โปรไฟล์การตรวจเป็นแบบ allowlist: RSA หรือ ECDSA กับ SHA-256, SHA-384 หรือ SHA-512; digest method SHA-256, SHA-384 หรือ SHA-512; exclusive canonicalization เท่านั้น; และคู่ transform enveloped-signature บวก exclusive-C14N อย่างพอดีบน ds:Reference ที่ครอบคลุมรายการ อย่างอื่นจะล้มเหลวด้วย unsupported_algorithm หรือ unsupported_transform
  • TslFetcher ปฏิเสธ URL ที่ไม่ใช่ HTTPS และใช้ SSRF guard ก่อน egress ใด ๆ ภายใต้ NetworkPolicy::STRICT_OFFLINE มันจะเสิร์ฟเนื้อหาที่แคชไว้ก่อนหน้าหรือยก NetworkPolicyViolation; ไม่มีการส่งคำขอออกไปนอกเลย
  • รายการล้าสมัย TslParseException จาก verifyXml(), assertFresh() หรือ buildBundle() หมายความว่าแหล่ง trust ใช้ไม่ได้ จงถือว่าเป็นความล้มเหลวในการรีเฟรชเชิงปฏิบัติการ ไม่ใช่คำตัดสินเรื่องลายเซ็น
  • nextUpdate ที่ไม่เป็นบัญญัติ ค่าที่ไม่มี Z หรือ numeric offset อย่างชัดเจนจะ throw แทนที่จะ parse แบบผ่อนปรน ETSI TS 119 612 §5.1.3 กำหนดรูปแบบ UTC Z; เกตยังยอมรับ numeric offset อย่างชัดเจนและปฏิเสธทุกอย่างอื่น
  • การเลื่อนของเวลาที่ใช้งาน verifyXml() เกต ณ เวลาตรวจ; เอกสารที่ถือไว้ในหน่วยความจำเลย nextUpdate ยังคงล้มเหลวที่เกต buildBundle($tsl, $now) ในภายหลัง
  • การกำหนดค่า anchor ว่างเปล่า TslSignatureVerifier ปฏิเสธการสร้างด้วยรายการ anchor ว่างเปล่า (InvalidArgumentException)
  • ไม่มีบริการที่ใช้ได้ รายการที่ยังใหม่แต่ไม่มีบริการ CA/QC ที่ granted จะยก TslParseException จาก buildBundle(); ไม่มีการผลิตชุดที่ว่างเปล่าเลย
  • ท่าทีออฟไลน์ STRICT_OFFLINE ที่ไม่มีเนื้อหาแคชจะยก NetworkPolicyViolation การค้นหาในแคชมาก่อนการตรวจนโยบาย ดังนั้นรายการที่แคชไว้จึงทำให้การตรวจสอบแบบ air-gapped ทำงานต่อไปได้
  • การตอบสนองที่ใหญ่เกินหรือว่างเปล่า fetch() อ่านได้มากที่สุด $maxBytes ไบต์ (ค่าเริ่มต้น 16 MiB); รายการที่ถูกตัดทอนจะล้มเหลวในการตรวจ digest ในขั้นตอนถัดไป เนื้อหาที่ว่างเปล่าจะยก TslFetchException
  • DOCTYPE ใน XML DOCTYPE ใด ๆ ถูกปฏิเสธก่อนที่ libxml จะสร้างตาราง entity และปฏิเสธอีกครั้งหลังโหลด สิ่งนี้ปิดคลาสอินพุต XXE และ entity-expansion (billion-laughs)
  • ลายเซ็นหลายรายการ เฉพาะ ds:Signature แบบ enveloped ที่ตรวจแล้วเท่านั้นที่ถูกลบออกก่อนคำนวณ digest; ลายเซ็นพี่น้องและ counter-signature ถูกเก็บรักษาไว้ อนุญาต reference ของ XAdES เพิ่มเติมได้ แต่ต้องมี ds:Reference หนึ่งรายการพอดีที่ครอบคลุม document root
  • สาระของห่วงโซ่ที่หมดอายุ ผู้ลงนาม, intermediate หรือ anchor ที่หมดอายุหรือยังไม่ถึงกำหนดใช้จะล้มเหลวด้วยเหตุผล expired_anchor โดย clockTolerance ขยายหน้าต่างการยอมรับอย่างสมมาตรและมีค่าเริ่มต้นเป็น 0

allowlist ของตัวตรวจถูกตรึงไว้ที่ RSA และ ECDSA กับตระกูล SHA-2; SHA-1 และ MD5 ถูกกันออกเชิงโครงสร้าง เลขคณิตของลายเซ็นรันในการเข้ารหัสด้วยซอฟต์แวร์ที่รวมมาให้ (phpseclib) NextPDF ไม่อ้างการรับรอง FIPS 140-3 สำหรับเลขคณิตนั้น โปรไฟล์นโยบายการเข้ารหัส FIPS 140-3 ของ Enterprise มีเอกสารกำกับพร้อมกับโมดูล security; มันจำกัดการเลือกอัลกอริทึมและไม่เปลี่ยนโครงสร้าง trusted-list หรือพฤติกรรม fail-closed ของโมดูลนี้

ClaimStandardClause
trusted list ที่ Next update ผ่านไปแล้วจะถูกทิ้งเนื่องจากหมดอายุETSI TS 119 612§5.3.15
ฟิลด์วันที่และเวลาเป็นสตริง ISO 8601 ในรูปแบบ UTC พร้อม designator ZETSI TS 119 612§5.1.3
ผู้ดำเนินการสคีมลงนาม trusted list เพื่อความแท้จริงและความสมบูรณ์ETSI TS 119 612§5.7.1
สถานะบริการที่ผ่านการรับรองคือ status URI แบบ granted หรือ withdrawnETSI TS 119 612§5.5.4
CA ที่ผ่านการรับรองระบุด้วย service-type URI Svctype/CA/QCETSI TS 119 612§5.5.1.1
TSL sequence number เริ่มที่ 1 และเพิ่มขึ้นในแต่ละรุ่นETSI TS 119 612§5.3.2

ทุก clause ถูกถอดความ; NextPDF ไม่ทำซ้ำข้อความเชิงบรรทัดฐาน NextPDF ไม่อ้างความสอดคล้องกับ ETSI TS 119 612 และไม่อ้างการรับรอง eIDAS การบริโภค trusted list ไม่ทำให้ลายเซ็น ใบรับรอง หรือผลลัพธ์ของ NextPDF กลายเป็น “qualified”; การรับรองคุณสมบัติเป็นของผู้ให้บริการ trust ภายใต้การกำกับดูแลของรัฐสมาชิก และผลทางกฎหมายอยู่นอกโมดูลนี้ ข้อจำกัดของ processing-model ของ XMLDSig (enveloped-signature transform, exclusive canonicalization, root-covering reference) มีเอกสารกำกับจากโปรไฟล์การตรวจของผลิตภัณฑ์; ข้อกำหนด W3C XML Signature อยู่นอกชุดหลักฐานที่อ้างอิง โมดูลนี้ตัดสินเพียงว่ารายการหนึ่งยอมรับได้ในฐานะอินพุต trust หรือไม่; การตรวจสอบ certificate-path เทียบกับ anchor ที่ได้เป็นของเลเยอร์ certificate-validation

  • ทรัพยากรพึ่งพาเป็นอินเทอร์เฟซ PSR: ไคลเอนต์ PSR-18, request factory PSR-17 และแคช PSR-16 ที่เป็นตัวเลือก ฉีด double แบบ in-memory ในการทดสอบ; ไม่มีขั้นตอนใดต้องการการเข้าถึงเครือข่ายจริงยกเว้น fetch() แบบ cold
  • ตรึง anchor บนสุดแบบ out of band สำหรับรายการของรัฐสมาชิก LOTL anchor ให้สิทธิ์ผู้ลงนามรายการ; ตัวตรวจไม่เคย bootstrap trust จากเนื้อหา KeyInfo
  • การ polling เบื้องหลัง การประมวลผล pivot-LOTL และการยืนยันตัวตนแบบ mutual-TLS หรือ proxy อยู่นอกขอบเขตของ fetcher ในเวอร์ชันนี้ จัดตารางการรีเฟรชจากภายนอกและ re-fetch ก่อน nextUpdate แต่ละครั้ง
  • ส่งช่วงเวลาการตรวจสอบ ไม่ใช่ช่วงเวลาการสร้าง ไปยัง buildBundle() สร้างชุดใหม่หลังการรีเฟรชแต่ละครั้ง; อย่าแคชชุดเลย nextUpdate ของรายการต้นทาง
  • bundleVersion มีรูปแบบที่สังเกตได้ tsl-<territory>-seq<sequenceNumber>; rawXmlSha256 บน TslDocument รองรับบันทึกหลักฐานและการตรวจจับ replay
  • รายการบริการที่ผิดรูปจะ parse ด้วยค่า placeholder เชิงป้องกัน; digital identity ที่ผิดรูปซึ่งไปถึงการสร้างชุดจะ fail closed ด้วย InvalidArgumentException
  • คลาสต่าง ๆ มี annotation ต้นทาง @since 1.10.0 (TslFetchException: 3.2.0) ส่วน TslDocument, TspService และ TspServiceQualifier มี annotation @api ที่ต้นทาง

หน้านี้บันทึกเฉพาะพฤติกรรมที่สังเกตได้จากภายนอกและพื้นผิว API สาธารณะที่รองรับเท่านั้น เส้นทางเนมสเปซภายใน คลาสตัวช่วย ตารางกลไก ชื่อไฟล์ runbook และ prefix ของ ticket อยู่นอกขอบเขต