Bỏ qua để đến nội dung
getnextpdf.com

Enterprise phiên bản

Trusted lists — Tài liệu tham chiếu chuyên sâu

Trang này là tham chiếu chuyên sâu cho bề mặt trusted-list trong NextPDF Enterprise. Bề mặt này gồm mười hai lớp công khai của namespace NextPDF\Enterprise\Security\Tsl. NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer là điểm vào được điều phối: nó chỉ trả về một TslDocument khi việc fetch HTTP, xác minh XMLDSig, parse cấu trúc, và cổng kiểm tra hết hạn nextUpdate đều vượt qua. Sau đó TslTrustAnchorProvider::buildBundle() suy dẫn một bundle trust-anchor từ các dịch vụ CA/QC đang hoạt động, khẳng định lại độ mới tại một thời điểm do bên gọi cung cấp trước khi trích xuất bất kỳ anchor nào. Mọi thất bại đều ném ra một ngoại lệ có kiểu; không giai đoạn nào suy giảm âm thầm. Pipeline hỗ trợ xác minh các trusted list của quốc gia thành viên EU và các trust anchor có nguồn từ LOTL (List of Trusted Lists) khi được bên gọi cung cấp; việc tự động khám phá LOTL, polling, và xử lý pivot nằm ngoài phạm vi.

Năng lực này được cung cấp trong NextPDF Enterprise (nextpdf/enterprise) và kích hoạt bằng một envelope giấy phép cấp Enterprise. Một triển khai không có quyền đó sẽ không nạp các lớp của năng lực này. So sánh các ấn bản và nhận giấy phép.

Ký hiệuTham sốHành vi mặc địnhTrả vềNém hoặc thất bại vớiGhi chú
TslPolicyEnforcerTslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parserKết hợp fetch, verify chữ ký, parse, và cổng kiểm tra hết hạn thành một điểm vào duy nhấtTruyền tiếp các ngoại lệ pipeline bên dướifinal; fail-closed theo thiết kế
TslPolicyEnforcer::fetchAndVerifystring $urlFetch một TSL, rồi chạy verifyXml() trên các byteTslDocumentTslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseExceptionChỉ trả về khi cả bốn giai đoạn vượt qua
TslPolicyEnforcer::verifyXmlstring $xmlXác minh chữ ký, parse, và từ chối một danh sách cũTslDocumentTslSignatureException, TslParseExceptionĐộ cũ được đánh giá theo giờ hệ thống hiện tại
TslFetcherClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINETruy xuất TSL/LOTL chỉ qua HTTPS với cache dựa trên ETagfinal; bảo vệ SSRF chặn các host riêng tư, loopback, link-local, và metadata với biện pháp giảm thiểu DNS-rebinding
TslFetcher::fetchstring $urlGET với revalidation If-None-Match; cache phần body cùng ETag theo TTL đã cấu hìnhstring (byte XML thô)TslFetchException, NetworkPolicyViolationĐọc tối đa $maxBytes byte; dưới STRICT_OFFLINE chỉ phục vụ body đã được cache
TslSignatureVerifierarray $trustAnchorsPem, int $clockTolerance = 0Trình xác minh XMLDSig được ghim vào các trust anchor đã cấu hìnhInvalidArgumentException khi danh sách anchor rỗngfinal; allowlist trong ALLOWED_SIG_ALGALLOWED_DIGEST_ALG
TslSignatureVerifier::verifystring $xmlXác minh chữ ký XMLDSig enveloped theo lối fail-closedstring (PEM chứng chỉ của bên ký)TslSignatureException kèm mã lý do đọc được bằng máyCác chứng chỉ trong KeyInfo không bao giờ tự được tin cậy; bên ký phải chain tới một anchor đã cấu hình
TslXmlParser::parsestring $xmlParse cấu trúc thành một TslDocument; không quan tâm chữ kýTslDocumentTslParseExceptionTừ chối mọi DOCTYPE theo lối fail-closed trước khi parse; nạp với LIBXML_NONET; bên gọi phải verify trước khi tin cậy kết quả
TslTrustAnchorProvider::buildBundleTslDocument $tsl, DateTimeImmutable $nowKhẳng định độ mới trước, rồi thu thập các chứng chỉ của những dịch vụ CA/QC đang hoạt độngEnterpriseCaTrustAnchorBundleTslParseExceptionCổng kiểm tra độ mới đứng trước mọi trích xuất anchor; tập kết quả rỗng sẽ ném
TslDocumentTám thuộc tính readonly được promote (xem khối constructor)Value object của TSL đã parse, bất biếnfinal readonly; được chú thích @api ở nguồn
TslDocument::isStaleDateTimeImmutable $nowSo sánh nextUpdate với $now sau một lần parse UTC fail-closedboolTslParseExceptionYêu cầu một designator Z tường minh hoặc offset dạng số
TslDocument::assertFreshDateTimeImmutable $nowNém khi danh sách cũ hoặc nextUpdate không parse đượcvoidTslParseExceptionCổng kiểm tra độ mới ở ranh giới người tiêu thụ
TslDocument::servicesOfTypestring $serviceTypeIdentifierLọc các dịch vụ theo URI kiểu-dịch-vụ của ETSIlist<TspService>Không ném
TslDocument::activeServicesTrả về các dịch vụ chỉ ở trạng thái grantedlist<TspService>Không némGranted nghĩa là TspService::STATUS_GRANTED
TspServiceTám thuộc tính readonly được promoteMột mục dịch-vụ-tin-cậy bên trong một TSLfinal readonly; hằng số cho trạng thái và các URI kiểu-dịch-vụ
TspService::isGrantedSo sánh bằng trạng thái với URI grantedboolKhông ném
TspService::isQualifiedCaSo sánh bằng kiểu với URI CA/QCboolKhông ném
TspServiceQualifierstring $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = []Một qualifier dịch vụ ETSI với tiêu chí tùy chọnfinal readonly; hằng số FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD
EnterpriseCaTrustAnchorBundlearray $anchorsPem, string $bundleVersion, string $bundleSha256Bundle anchor được ghim; kiểm chứng digest cung cấp so với các anchor cung cấp tại thời điểm khởi tạoInvalidArgumentExceptionLấy từ buildBundle(); không khởi tạo thủ công; hiện thực TrustAnchorStoreInterface
EnterpriseCaTrustAnchorBundle::containsFingerprintstring $anchorDerSha256HexThành viên anchor theo SHA-256 dạng hex trên phần thân DERboolKhông ném
EnterpriseCaTrustAnchorBundle::computeBundleSha256array $anchorsPemSHA-256 chuẩn tắc trên chuỗi PEM đã ghép và chuẩn hóa newlinestringKhông némstatic
TslFetchExceptionBáo hiệu một lần truy xuất TSL thất bạifinal; kế thừa RuntimeException
TslParseExceptionBáo hiệu một thất bại về cấu trúc hoặc độ mớifinal; kế thừa RuntimeException
TslSignatureExceptionstring $reason, string $messageBáo hiệu thất bại xác minh XMLDSig kèm một mã lý dofinal; công khai readonly $reason (xem các mã lý do bên dưới)

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)

Các mã lý do của TslSignatureException: missing_signature, untrusted_signer, invalid_signature, digest_mismatch, unsupported_algorithm, unsupported_transform, expired_anchor.

  • Thứ tự pipeline là cố định: fetch, xác minh XMLDSig, parse cấu trúc, cổng kiểm tra độ cũ. TslPolicyEnforcer chỉ trả về một TslDocument khi cả bốn đều thành công. Một trusted list được scheme operator ký để các bên phụ thuộc có thể kiểm tra tính xác thực và tính toàn vẹn — ETSI TS 119 612 §5.7.1.
  • TslXmlParser không quan tâm chữ ký theo thiết kế. Bên gọi phải xác minh chữ ký trước khi tin cậy bất kỳ trường nào đã parse. TslPolicyEnforcer::verifyXml() thực thi thứ tự đó.
  • Bất biến về độ mới được thực thi tại mọi ranh giới người tiêu thụ. Một danh sách có nextUpdate đã qua là hết hạn và bị từ chối — ETSI TS 119 612 §5.3.15. verifyXml() chặn theo giờ hệ thống hiện tại; TslDocument::assertFresh()buildBundle() chặn theo một thời điểm do bên gọi cung cấp.
  • Việc parse độ mới là fail-closed. Các trường ngày-giờ là giá trị ISO 8601 UTC với một designator tường minh — ETSI TS 119 612 §5.1.3. Một nextUpdate không có Z tường minh hoặc offset dạng số sẽ ném TslParseException; giá trị này không bao giờ được diễn giải lại theo múi giờ cục bộ của máy chủ.
  • buildBundle() gọi assertFresh($now) trước khi trích xuất bất kỳ anchor nào, rồi chỉ nhận các dịch vụ vừa granted vừa CA/QC. Granted và withdrawn là các URI trạng thái của dịch vụ đủ tiêu chuẩn — ETSI TS 119 612 §5.5.4. CA/QC là URI kiểu-dịch-vụ của CA đủ tiêu chuẩn — ETSI TS 119 612 §5.5.1.1.
  • Phiên bản bundle được suy dẫn từ scheme territory và số thứ tự TSL. Số thứ tự là đơn điệu qua các bản phát hành — ETSI TS 119 612 §5.3.2. Digest của bundle là một SHA-256 chuẩn tắc trên các PEM anchor, và containsFingerprint() trả lời về thành viên bằng SHA-256 của DER.
  • Trình xác minh chỉ tin cậy các anchor đã cấu hình. Các chứng chỉ tìm thấy trong KeyInfo đóng vai trò là leaf của bên ký và là các trung gian ứng viên; chain phải chạm tới một anchor đã cấu hình trong độ sâu 8, mọi mắt xích phải hợp lệ về mặt thời gian, và một chứng chỉ phát hành phải mang basicConstraints cA=TRUE (cùng keyCertSign khi keyUsage hiện diện).
  • Hồ sơ xác minh là một allowlist: RSA hoặc ECDSA với SHA-256, SHA-384, hoặc SHA-512; các phương thức digest SHA-256, SHA-384, hoặc SHA-512; chỉ canonicalization độc quyền; và đúng cặp transform enveloped-signature cộng exclusive-C14N trên ds:Reference bao trùm danh sách. Bất cứ thứ gì khác đều thất bại với unsupported_algorithm hoặc unsupported_transform.
  • TslFetcher từ chối các URL không phải HTTPS và áp dụng một bảo vệ SSRF trước bất kỳ luồng ra nào. Dưới NetworkPolicy::STRICT_OFFLINE nó phục vụ một body đã cache trước đó hoặc ném NetworkPolicyViolation; không có yêu cầu đi ra nào từng được gửi.
  • Danh sách cũ. TslParseException từ verifyXml(), assertFresh(), hoặc buildBundle() nghĩa là nguồn tin cậy không dùng được. Hãy xem đó là một thất bại làm mới về vận hành, không phải một phán quyết về chữ ký.
  • nextUpdate không chuẩn tắc. Một giá trị không có Z tường minh hoặc offset dạng số sẽ ném thay vì parse một cách khoan dung. ETSI TS 119 612 §5.1.3 bắt buộc dạng UTC Z; cổng này cũng chấp nhận một offset dạng số tường minh và từ chối mọi thứ khác.
  • Trôi thời điểm sử dụng. verifyXml() chặn tại thời điểm xác minh; một tài liệu giữ trong bộ nhớ quá nextUpdate vẫn thất bại tại cổng buildBundle($tsl, $now) sau đó.
  • Cấu hình anchor rỗng. TslSignatureVerifier từ chối khởi tạo với một danh sách anchor rỗng (InvalidArgumentException).
  • Không có dịch vụ dùng được. Một danh sách mới không có dịch vụ CA/QC granted nào sẽ ném TslParseException từ buildBundle(); một bundle rỗng không bao giờ được tạo ra.
  • Tư thế offline. STRICT_OFFLINE không có body đã cache sẽ ném NetworkPolicyViolation. Việc tra cứu cache đứng trước lần kiểm tra chính sách, nên một danh sách đã cache giữ cho việc kiểm định air-gapped tiếp tục hoạt động.
  • Phản hồi quá cỡ hoặc rỗng. fetch() đọc tối đa $maxBytes byte (mặc định 16 MiB); một danh sách bị cắt cụt sau đó thất bại xác minh digest ở khâu sau. Một body rỗng sẽ ném TslFetchException.
  • DOCTYPE trong XML. Mọi DOCTYPE đều bị từ chối trước khi libxml dựng bảng thực thể, và lại một lần nữa sau khi nạp. Điều này đóng các lớp đầu vào XXE và bùng nổ thực thể (billion-laughs).
  • Nhiều chữ ký. Chỉ ds:Signature enveloped đã được xác minh mới bị gỡ trước khi tính digest; các chữ ký anh em và counter-signature được giữ lại. Cho phép các tham chiếu XAdES bổ sung, nhưng đúng một ds:Reference phải bao trùm gốc tài liệu.
  • Vật liệu chain đã hết hạn. Một bên ký, trung gian, hoặc anchor đã hết hạn hoặc chưa hợp lệ sẽ thất bại với lý do expired_anchor. clockTolerance mở rộng cửa sổ chấp nhận một cách đối xứng và mặc định là 0.

Allowlist của trình xác minh được cố định vào RSA và ECDSA với họ SHA-2; SHA-1 và MD5 bị loại trừ về mặt cấu trúc. Số học chữ ký chạy trong phần mềm mật mã đóng gói kèm (phpseclib). NextPDF không đưa ra tuyên bố xác nhận FIPS 140-3 nào cho số học đó. Hồ sơ chính sách mật mã FIPS 140-3 của Enterprise được tài liệu hóa cùng với module bảo mật; nó ràng buộc việc lựa chọn thuật toán và không thay đổi các cấu trúc trusted-list hay hành vi fail-closed của module này.

Tuyên bốTiêu chuẩnĐiều khoản
Một trusted list có Next update đã qua bị loại bỏ vì hết hạn.ETSI TS 119 612§5.3.15
Các trường ngày-giờ là chuỗi ISO 8601 theo UTC với designator Z.ETSI TS 119 612§5.1.3
Scheme operator ký trusted list để đảm bảo tính xác thực và tính toàn vẹn.ETSI TS 119 612§5.7.1
Trạng thái dịch vụ đủ tiêu chuẩn là URI trạng thái granted hoặc withdrawn.ETSI TS 119 612§5.5.4
Một CA đủ tiêu chuẩn được nhận diện bằng URI kiểu-dịch-vụ Svctype/CA/QC.ETSI TS 119 612§5.5.1.1
Số thứ tự TSL bắt đầu từ 1 và tăng dần theo mỗi bản phát hành.ETSI TS 119 612§5.3.2

Mọi điều khoản đều được diễn giải lại; NextPDF không tái tạo văn bản quy phạm. NextPDF không đưa ra tuyên bố tuân thủ ETSI TS 119 612 nào và không tuyên bố chứng nhận eIDAS nào. Việc tiêu thụ một trusted list không làm cho một chữ ký, một chứng chỉ, hay một đầu ra của NextPDF trở nên “đủ tiêu chuẩn”; tính đủ tiêu chuẩn thuộc về nhà cung cấp dịch vụ tin cậy dưới sự giám sát của quốc gia thành viên, và hiệu lực pháp lý nằm ngoài module này. Các ràng buộc mô hình xử lý XMLDSig (enveloped-signature transform, canonicalization độc quyền, tham chiếu bao trùm gốc) được tài liệu hóa từ hồ sơ xác minh của sản phẩm; đặc tả W3C XML Signature nằm ngoài tập bằng chứng được trích dẫn. Module này chỉ quyết định liệu một danh sách có được chấp nhận làm đầu vào tin cậy hay không; việc kiểm định đường dẫn chứng chỉ so với các anchor thu được thuộc về lớp kiểm định chứng chỉ.

  • Các phụ thuộc là các interface PSR: một PSR-18 client, một PSR-17 request factory, và một PSR-16 cache tùy chọn. Hãy tiêm các double trong bộ nhớ trong test; không giai đoạn nào cần truy cập mạng trực tiếp ngoại trừ một fetch() khi cache nguội.
  • Hãy ghim anchor đỉnh ngoài băng thông. Đối với danh sách của quốc gia thành viên, LOTL anchor ủy quyền cho các bên ký danh sách; trình xác minh không bao giờ bootstrap sự tin cậy từ nội dung KeyInfo.
  • Polling nền, xử lý pivot-LOTL, và xác thực mutual-TLS hay proxy nằm ngoài phạm vi của fetcher trong phiên bản này. Hãy lên lịch làm mới từ bên ngoài và re-fetch trước mỗi nextUpdate.
  • Hãy truyền thời điểm kiểm định, không phải thời điểm khởi tạo, cho buildBundle(). Hãy dựng lại bundle sau mỗi lần làm mới; không bao giờ cache một bundle quá nextUpdate của danh sách nguồn.
  • bundleVersion có hình dạng quan sát được tsl-<territory>-seq<sequenceNumber>; rawXmlSha256 trên TslDocument hỗ trợ các bản ghi bằng chứng và phát hiện replay.
  • Các mục dịch vụ dị dạng parse với các giá trị placeholder phòng thủ; một digital identity dị dạng chạm tới việc dựng bundle sẽ fail closed với InvalidArgumentException.
  • Các lớp mang chú thích nguồn gói @since 1.10.0 (TslFetchException: 3.2.0). TslDocument, TspService, và TspServiceQualifier được chú thích nguồn @api.

Trang này chỉ tài liệu hóa hành vi quan sát được từ bên ngoài và bề mặt API công khai được hỗ trợ. Các đường dẫn namespace nội bộ, lớp trợ giúp, bảng cơ chế, tên tệp runbook, và tiền tố ticket nằm ngoài phạm vi.