Ir al contenido
getnextpdf.com

Enterprise edición

Listas de confianza — Referencia detallada

Esta página es la referencia detallada de la superficie de listas de confianza en NextPDF Enterprise. La superficie está formada por las doce clases públicas del espacio de nombres NextPDF\Enterprise\Security\Tsl. NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer es el punto de entrada orquestado: devuelve un TslDocument solo cuando la descarga HTTP, la verificación XMLDSig, el análisis estructural y la puerta de caducidad nextUpdate superan todas las comprobaciones. TslTrustAnchorProvider::buildBundle() deriva entonces un paquete de anclas de confianza a partir de los servicios CA/QC activos, reafirmando la frescura en un instante suministrado por el llamante antes de extraer cualquier ancla. Todo fallo lanza una excepción tipada; ninguna etapa se degrada de forma silenciosa. La canalización admite la verificación de las listas de confianza de los Estados miembros de la UE y de las anclas de confianza procedentes de la LOTL (List of Trusted Lists) cuando las suministra el llamante; el descubrimiento automático de la LOTL, el sondeo y el procesamiento de pivotes quedan fuera del alcance.

Esta capacidad se distribuye con NextPDF Enterprise (nextpdf/enterprise) y se activa con un sobre de licencia de nivel Enterprise. Una implantación sin ese derecho no carga las clases de la capacidad. Comparar ediciones y obtener una licencia.

SímboloParámetrosComportamiento predeterminadoDevuelveLanza o falla conNotas
TslPolicyEnforcerTslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parserCombina descarga, verificación de firma, análisis y puerta de caducidad en un único punto de entradaPropaga las excepciones de la canalización que figuran abajofinal; con cierre seguro por construcción
TslPolicyEnforcer::fetchAndVerifystring $urlDescarga una TSL y luego ejecuta verifyXml() sobre los bytesTslDocumentTslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseExceptionDevuelve solo cuando las cuatro etapas superan las comprobaciones
TslPolicyEnforcer::verifyXmlstring $xmlVerifica la firma, analiza y rechaza una lista caducadaTslDocumentTslSignatureException, TslParseExceptionLa caducidad se evalúa frente a la hora actual del sistema
TslFetcherClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINERecuperación TSL/LOTL solo por HTTPS con caché basada en ETagfinal; la protección SSRF bloquea hosts privados, de bucle local, de enlace local y de metadatos con mitigación de reasignación de DNS
TslFetcher::fetchstring $urlGET con revalidación If-None-Match; almacena en caché el cuerpo más el ETag bajo el TTL configuradostring (bytes XML en bruto)TslFetchException, NetworkPolicyViolationLee como máximo $maxBytes bytes; bajo STRICT_OFFLINE solo se sirve un cuerpo en caché
TslSignatureVerifierarray $trustAnchorsPem, int $clockTolerance = 0Verificador XMLDSig fijado a las anclas de confianza configuradasInvalidArgumentException cuando la lista de anclas está vacíafinal; listas de permitidos en ALLOWED_SIG_ALG y ALLOWED_DIGEST_ALG
TslSignatureVerifier::verifystring $xmlVerifica la firma XMLDSig envuelta con cierre segurostring (PEM del certificado firmante)TslSignatureException con un código de motivo legible por máquinaLos certificados de KeyInfo nunca se confían por sí solos; el firmante debe encadenar hasta un ancla configurada
TslXmlParser::parsestring $xmlAnálisis estructural en un TslDocument; agnóstico a la firmaTslDocumentTslParseExceptionRechaza cualquier DOCTYPE con cierre seguro antes del análisis; carga con LIBXML_NONET; los llamantes deben verificar antes de confiar en el resultado
TslTrustAnchorProvider::buildBundleTslDocument $tsl, DateTimeImmutable $nowAfirma primero la frescura y luego recopila los certificados de los servicios CA/QC activosEnterpriseCaTrustAnchorBundleTslParseExceptionLa puerta de frescura precede a cualquier extracción de ancla; un conjunto de resultados vacío lanza excepción
TslDocumentOcho propiedades readonly promovidas (véase el bloque del constructor)Objeto de valor TSL analizado e inmutablefinal readonly; anotado en origen con @api
TslDocument::isStaleDateTimeImmutable $nowCompara nextUpdate con $now tras un análisis UTC con cierre seguroboolTslParseExceptionRequiere un designador Z explícito o un desfase numérico
TslDocument::assertFreshDateTimeImmutable $nowLanza excepción cuando la lista está caducada o nextUpdate no es analizablevoidTslParseExceptionLa puerta de frescura del límite del consumidor
TslDocument::servicesOfTypestring $serviceTypeIdentifierFiltra los servicios por URI de tipo de servicio ETSIlist<TspService>No lanza excepción
TslDocument::activeServicesDevuelve solo los servicios en estado grantedlist<TspService>No lanza excepciónGranted significa TspService::STATUS_GRANTED
TspServiceOcho propiedades readonly promovidasUna entrada de servicio de confianza dentro de una TSLfinal readonly; constantes para las URI de estado y de tipo de servicio
TspService::isGrantedIgualdad de estado frente a la URI grantedboolNo lanza excepción
TspService::isQualifiedCaIgualdad de tipo frente a la URI CA/QCboolNo lanza excepción
TspServiceQualifierstring $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = []Un cualificador de servicio ETSI con criterios opcionalesfinal readonly; constantes FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD
EnterpriseCaTrustAnchorBundlearray $anchorsPem, string $bundleVersion, string $bundleSha256Paquete de anclas fijadas; valida el resumen suministrado frente a las anclas suministradas en la construcciónInvalidArgumentExceptionObténgalo de buildBundle(); no lo construya a mano; implementa TrustAnchorStoreInterface
EnterpriseCaTrustAnchorBundle::containsFingerprintstring $anchorDerSha256HexPertenencia de ancla por SHA-256 hexadecimal sobre el cuerpo DERboolNo lanza excepción
EnterpriseCaTrustAnchorBundle::computeBundleSha256array $anchorsPemSHA-256 canónico sobre la concatenación PEM normalizada por saltos de líneastringNo lanza excepciónstatic
TslFetchExceptionSeñala una recuperación de TSL fallidafinal; extiende RuntimeException
TslParseExceptionSeñala un fallo estructural o de frescurafinal; extiende RuntimeException
TslSignatureExceptionstring $reason, string $messageSeñala un fallo de verificación XMLDSig con un código de motivofinal; readonly público $reason (véanse los códigos de motivo abajo)

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ódigos de motivo de TslSignatureException: missing_signature, untrusted_signer, invalid_signature, digest_mismatch, unsupported_algorithm, unsupported_transform, expired_anchor.

  • El orden de la canalización es fijo: descarga, verificación XMLDSig, análisis estructural, puerta de caducidad. TslPolicyEnforcer devuelve un TslDocument solo cuando las cuatro etapas tienen éxito. Una lista de confianza es firmada por su operador de esquema para que las partes usuarias puedan comprobar la autenticidad y la integridad — ETSI TS 119 612 §5.7.1.
  • TslXmlParser es agnóstico a la firma por diseño. Los llamantes deben verificar la firma antes de confiar en cualquier campo analizado. TslPolicyEnforcer::verifyXml() impone ese orden.
  • El invariante de frescura se aplica en cada límite del consumidor. Una lista cuyo nextUpdate ya ha pasado está caducada y se rechaza — ETSI TS 119 612 §5.3.15. verifyXml() comprueba frente a la hora actual del sistema; TslDocument::assertFresh() y buildBundle() comprueban frente a un instante suministrado por el llamante.
  • El análisis de frescura es de cierre seguro. Los campos de fecha y hora son valores ISO 8601 en UTC con un designador explícito — ETSI TS 119 612 §5.1.3. Un nextUpdate sin un Z explícito o un desfase numérico lanza TslParseException; el valor nunca se reinterpreta en la zona horaria local del servidor.
  • buildBundle() llama a assertFresh($now) antes de extraer ninguna ancla y luego admite únicamente los servicios que son a la vez granted y CA/QC. Granted y withdrawn son las URI de estado de servicio cualificado — ETSI TS 119 612 §5.5.4. CA/QC es la URI de tipo de servicio de CA cualificada — ETSI TS 119 612 §5.5.1.1.
  • La versión del paquete se deriva del territorio del esquema y del número de secuencia de la TSL. El número de secuencia es monótono a lo largo de las publicaciones — ETSI TS 119 612 §5.3.2. El resumen del paquete es un SHA-256 canónico sobre los PEM de las anclas, y containsFingerprint() responde a la pertenencia por SHA-256 DER.
  • El verificador confía únicamente en las anclas configuradas. Los certificados encontrados en KeyInfo sirven como hoja del firmante y como intermediarios candidatos; la cadena debe alcanzar un ancla configurada dentro de una profundidad de 8, cada enlace debe ser temporalmente válido y un certificado emisor debe llevar basicConstraints cA=TRUE (más keyCertSign cuando keyUsage está presente).
  • El perfil de verificación es una lista de permitidos: RSA o ECDSA con SHA-256, SHA-384 o SHA-512; métodos de resumen SHA-256, SHA-384 o SHA-512; solo canonicalización exclusiva; y exactamente el par de transformaciones de firma envuelta más C14N exclusiva en la ds:Reference que cubre la lista. Cualquier otra cosa falla con unsupported_algorithm o unsupported_transform.
  • TslFetcher rechaza las URL que no sean HTTPS y aplica una protección SSRF antes de cualquier salida. Bajo NetworkPolicy::STRICT_OFFLINE sirve un cuerpo previamente almacenado en caché o lanza NetworkPolicyViolation; nunca se envía ninguna petición saliente.
  • Lista caducada. Un TslParseException de verifyXml(), assertFresh() o buildBundle() significa que la fuente de confianza es inutilizable. Trátelo como un fallo operativo de actualización, no como un veredicto de firma.
  • nextUpdate no canónico. Un valor sin un Z explícito o un desfase numérico lanza excepción en lugar de analizarse de forma indulgente. ETSI TS 119 612 §5.1.3 exige la forma UTC Z; la puerta también acepta un desfase numérico explícito y rechaza todo lo demás.
  • Desfase en el momento de uso. verifyXml() comprueba en el momento de la verificación; un documento mantenido en memoria más allá de nextUpdate sigue fallando en la puerta posterior buildBundle($tsl, $now).
  • Configuración de anclas vacía. TslSignatureVerifier rechaza la construcción con una lista de anclas vacía (InvalidArgumentException).
  • Sin servicios utilizables. Una lista fresca sin servicios CA/QC en estado granted lanza un TslParseException desde buildBundle(); nunca se produce un paquete vacío.
  • Postura sin conexión. STRICT_OFFLINE sin cuerpo en caché lanza NetworkPolicyViolation. La búsqueda en caché precede a la comprobación de la política, de modo que una lista en caché mantiene operativa la validación aislada de la red.
  • Respuesta sobredimensionada o vacía. fetch() lee como máximo $maxBytes bytes (16 MiB por defecto); una lista truncada falla entonces la verificación de resumen aguas abajo. Un cuerpo vacío lanza TslFetchException.
  • DOCTYPE en el XML. Cualquier DOCTYPE se rechaza antes de que libxml construya una tabla de entidades, y de nuevo tras la carga. Esto cierra las clases de entrada XXE y de expansión de entidades (billion-laughs).
  • Firmas múltiples. Solo se elimina la ds:Signature envuelta verificada antes del cálculo del resumen; las firmas hermanas y las contrafirmas se conservan. Se permiten referencias XAdES adicionales, pero exactamente una ds:Reference debe cubrir la raíz del documento.
  • Material de cadena caducado. Un firmante, intermediario o ancla caducado o aún no válido falla con el motivo expired_anchor. clockTolerance amplía la ventana de aceptación de forma simétrica y su valor predeterminado es 0.

La lista de permitidos del verificador está fijada a RSA y ECDSA con la familia SHA-2; SHA-1 y MD5 quedan estructuralmente excluidos. La aritmética de firma se ejecuta en criptografía de software incluida (phpseclib). NextPDF no formula ninguna afirmación de validación FIPS 140-3 para esa aritmética. El perfil de política criptográfica FIPS 140-3 de Enterprise está documentado con el módulo de seguridad; restringe la selección de algoritmos y no cambia las estructuras de las listas de confianza ni el comportamiento de cierre seguro de este módulo.

AfirmaciónEstándarCláusula
Una lista de confianza cuyo Next update ha pasado se descarta por caducada.ETSI TS 119 612§5.3.15
Los campos de fecha y hora son cadenas ISO 8601 en UTC con el designador Z.ETSI TS 119 612§5.1.3
El operador de esquema firma la lista de confianza para dar autenticidad e integridad.ETSI TS 119 612§5.7.1
El estado de servicio cualificado es la URI de estado granted o withdrawn.ETSI TS 119 612§5.5.4
Una CA cualificada se identifica mediante la URI de tipo de servicio Svctype/CA/QC.ETSI TS 119 612§5.5.1.1
El número de secuencia de la TSL comienza en 1 y se incrementa en cada publicación.ETSI TS 119 612§5.3.2

Todas las cláusulas están parafraseadas; NextPDF no reproduce el texto normativo. NextPDF no formula ninguna afirmación de conformidad con ETSI TS 119 612 ni ninguna afirmación de certificación eIDAS. Consumir una lista de confianza no convierte en «cualificada» a una firma, a un certificado ni a una salida de NextPDF; la cualificación corresponde al prestador de servicios de confianza bajo la supervisión del Estado miembro, y el efecto jurídico queda fuera de este módulo. Las restricciones del modelo de procesamiento XMLDSig (transformación de firma envuelta, canonicalización exclusiva, referencia que cubre la raíz) se documentan a partir del perfil de verificación del producto; la especificación W3C XML Signature queda fuera del conjunto de evidencias citadas. Este módulo decide únicamente si una lista es aceptable como entrada de confianza; la validación de la ruta de certificación frente a las anclas resultantes corresponde a la capa de validación de certificados.

  • Las dependencias son interfaces PSR: un cliente PSR-18, una fábrica de peticiones PSR-17 y una caché PSR-16 opcional. Inyecte dobles en memoria en las pruebas; ninguna etapa requiere acceso de red en vivo salvo un fetch() en frío.
  • Fije el ancla superior fuera de banda. Para las listas de los Estados miembros, el ancla LOTL autoriza a los firmantes de la lista; el verificador nunca arranca la confianza a partir del contenido de KeyInfo.
  • El sondeo en segundo plano, el procesamiento de LOTL de pivote y la autenticación TLS mutua o por proxy quedan fuera del alcance del descargador en esta versión. Programe la actualización externamente y vuelva a descargar antes de cada nextUpdate.
  • Pase a buildBundle() el instante de validación, no el instante de construcción. Reconstruya el paquete tras cada actualización; nunca almacene en caché un paquete más allá del nextUpdate de la lista de origen.
  • bundleVersion tiene la forma observable tsl-<territory>-seq<sequenceNumber>; rawXmlSha256 en TslDocument respalda los registros de evidencia y la detección de reproducción.
  • Las entradas de servicio malformadas se analizan con valores de marcador de posición defensivos; una identidad digital malformada que llega a la construcción del paquete falla con cierre seguro con InvalidArgumentException.
  • Las clases llevan anotaciones de origen de paquete @since 1.10.0 (TslFetchException: 3.2.0). TslDocument, TspService y TspServiceQualifier están anotadas en origen con @api.

Esta página documenta únicamente el comportamiento observable externamente y la superficie de la API pública admitida. Las rutas internas de espacios de nombres, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de ticket quedan fuera del alcance.