@owf/eudi-tl 0.4.0-alpha-20260901082001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["z","X509Certificate","SubjectKeyIdentifierExtension","hexEncode","base64","DOMParser","DOMParser","base64","compareBytes","base64"],"sources":["../src/constants.ts","../src/eu-lotl-anchors.ts","../src/trusted-list-exception.ts","../src/types.ts","../src/validate.ts","../src/parse.ts","../src/profiles.ts","../src/verify.ts","../src/eu-lotl.ts","../src/index.ts"],"sourcesContent":["/**\n * Well-known ETSI TS 119 612 URIs.\n *\n * These are the standard values used by eIDAS national trusted lists. Profiled\n * lists may use their own profile-specific URIs (validated via a caller-supplied\n * {@link ProfileRule}); this library's parser is agnostic to both.\n */\n\n/** Standard `TSLType` values (TS 119 612 clause 5.3.3). */\nexport const TSLType = {\n EUgeneric: 'http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUgeneric',\n EUlistofthelists: 'http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUlistofthelists',\n} as const\n\n/** Standard `ServiceStatus` values (TS 119 612 clause 5.5.4). */\nexport const ServiceStatus = {\n Granted: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted',\n Withdrawn: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/withdrawn',\n UnderSupervision: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/undersupervision',\n SupervisionCeased: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/supervisionceased',\n SupervisionInCessation: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/supervisionincessation',\n Accredited: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/accredited',\n AccreditationCeased: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/accreditationceased',\n AccreditationRevoked: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/accreditationrevoked',\n SetByNationalLaw: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/setbynationallaw',\n RecognisedAtNationalLevel: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/recognisedatnationallevel',\n DeprecatedAtNationalLevel: 'http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/deprecatedatnationallevel',\n} as const\n\n/**\n * Service statuses that denote a currently active / trustworthy service under\n * TS 119 612. Use as the `serviceStatus` filter when extracting trust anchors\n * from a standard eIDAS list; withdrawn/ceased services are excluded.\n */\nexport const ACTIVE_SERVICE_STATUSES: string[] = [\n ServiceStatus.Granted,\n ServiceStatus.UnderSupervision,\n ServiceStatus.Accredited,\n ServiceStatus.SetByNationalLaw,\n ServiceStatus.RecognisedAtNationalLevel,\n]\n\n/** Common standard `ServiceTypeIdentifier` values (TS 119 612 Annex D). */\nexport const ServiceType = {\n /** Qualified certificate CA. */\n CA_QC: 'http://uri.etsi.org/TrstSvc/Svctype/CA/QC',\n /** Public key certificate CA. */\n CA_PKC: 'http://uri.etsi.org/TrstSvc/Svctype/CA/PKC',\n /** Qualified timestamping authority. */\n TSA_QTST: 'http://uri.etsi.org/TrstSvc/Svctype/TSA/QTST',\n /** Qualified electronic delivery service. */\n EDS_Q: 'http://uri.etsi.org/TrstSvc/Svctype/EDS/Q',\n /** Qualified registered electronic mail delivery service. */\n EDS_REM_Q: 'http://uri.etsi.org/TrstSvc/Svctype/EDS/REM/Q',\n /** Qualified preservation service for electronic signatures/seals. */\n PSES_Q: 'http://uri.etsi.org/TrstSvc/Svctype/PSES/Q',\n /** Qualified validation service for qualified electronic signatures. */\n QESValidation_Q: 'http://uri.etsi.org/TrstSvc/Svctype/QESValidation/Q',\n /** OCSP responder for qualified certificates. */\n OCSP_QC: 'http://uri.etsi.org/TrstSvc/Svctype/Certstatus/OCSP/QC',\n} as const\n","/**\n * EU List of Trusted Lists (LOTL) signing certificates — GENERATED by\n * `scripts/refresh-lotl-anchors.mts`, do not edit by hand.\n *\n * These are the certificates the European Commission publishes as the signers\n * of the LOTL. They are the out-of-band trust anchor of the whole eIDAS trusted\n * list hierarchy: the set cannot be derived from the LOTL alone (a forged list\n * would carry a forged self-pointer), so it is pinned here and cross-checked\n * against the Official Journal publication referenced below.\n *\n * Source list: https://ec.europa.eu/tools/lotl/eu-lotl.xml\n * Official Journal: https://eur-lex.europa.eu/eli/C/2026/1944/oj\n */\n\n/** One certificate the European Commission publishes as a LOTL signer. */\nexport interface EuLotlSigningCertificate {\n /** base64-encoded DER. */\n certificate: string\n /** Subject distinguished name, for human review of the pinned set. */\n subject: string\n /** Lowercase-hex SHA-256 of the DER, for out-of-band cross-checking. */\n fingerprintSha256: string\n /** Certificate expiry (ISO 8601). */\n notAfter: string\n}\n\n/**\n * The signing certificates published by the LOTL identified in\n * {@link EU_LOTL_ANCHORS_PROVENANCE}. Any of them may sign a future issue of the\n * list, so the whole published set is pinned, not just the current signer.\n */\nexport const EU_LOTL_SIGNING_CERTIFICATES: readonly EuLotlSigningCertificate[] = [\n {\n certificate:\n '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',\n subject:\n 'C=LU, OU=Certificate Profile - Qualified Certificate - Organization, OU=Directorate-General for Digital Services, 2.5.4.97=LEIXG-254900ZNYA1FLUQ9U393, O=EUROPEAN COMMISSION, E=EU-TRUST@ec.europa.eu, CN=EUROPEAN COMMISSION',\n fingerprintSha256: '236103f03a8031ae8f47f9059bf8de38564cdbfebedde4a597d50f8980aa653b',\n notAfter: '2029-12-17T14:31:54.000Z',\n },\n {\n certificate:\n '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',\n subject:\n 'C=GR, OU=Certificate Profile - Qualified Certificate - Member, 2.5.4.97=LEIXG-254900ZNYA1FLUQ9U393, O=EUROPEAN COMMISSION, OU=Entitlement - EC STATUTORY STAFF, E=apostolos.apladas@ec.europa.eu, SN=APLADAS, G=APOSTOLOS, OU=RemoteQSCDManagement, CN=APOSTOLOS APLADAS',\n fingerprintSha256: 'b63d416744e7098bf9ec2caa596a93bc2468e37f8284ba65ecc061711bcbaa18',\n notAfter: '2027-04-26T12:49:22.000Z',\n },\n {\n certificate:\n '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',\n subject:\n 'C=GR, OU=Certificate Profile - Qualified Certificate - Member, 2.5.4.97=LEIXG-254900ZNYA1FLUQ9U393, O=EUROPEAN COMMISSION, OU=Entitlement - EC STATUTORY STAFF, E=Ioanna.KALOGEROPOULOU@ec.europa.eu, SN=KALOGEROPOULOU, G=IOANNA, OU=RemoteQSCDManagement, CN=IOANNA KALOGEROPOULOU',\n fingerprintSha256: 'c0641c4f7d56c431b1c924742db7fce9c1eef7d7fd212113a2768486b3abcdc5',\n notAfter: '2029-11-23T09:56:41.000Z',\n },\n {\n certificate:\n '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',\n subject: 'C=BE, CN=Patrick Kremer (Signature), SN=Kremer, G=Patrick Jean, 2.5.4.5=72020329970',\n fingerprintSha256: 'd2064fdd70f6982dcc516b86d9d5c56aea939417c624b2e478c0b29de54f8474',\n notAfter: '2028-05-30T23:59:59.000Z',\n },\n {\n certificate:\n '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',\n subject:\n 'C=ES, OU=Certificate Profile - Qualified Certificate - Member, 2.5.4.97=LEIXG-254900ZNYA1FLUQ9U393, O=EUROPEAN COMMISSION, OU=Entitlement - EC STATUTORY STAFF, E=vicente.andreu-navarro@ec.europa.eu, SN=ANDREU NAVARRO, G=VICENTE, OU=RemoteQSCDManagement, CN=VICENTE ANDREU NAVARRO',\n fingerprintSha256: 'df7e29360c34b2b8d6d5f40325c1d4d12c9922cecd33b7407674a74b2b3ca1e5',\n notAfter: '2027-05-06T12:45:16.000Z',\n },\n {\n certificate:\n 'MIIIoDCCBoigAwIBAgIUc8IcSUtVEKAMMvHm9QWU05kXsPUwDQYJKoZIhvcNAQENBQAwXzELMAkGA1UEBhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmljYWRvcmEgRGlnaXRhbDEkMCIGA1UEAwwbRElHSVRBTFNJR04gUVVBTElGSUVEIENBIEcxMB4XDTIzMTExNzEwMTE0NloXDTI3MTExNzEwMTE0NlowggEVMQswCQYDVQQGEwJMVTFDMEEGA1UECww6Q2VydGlmaWNhdGUgUHJvZmlsZSAtIFF1YWxpZmllZCBDZXJ0aWZpY2F0ZSAtIE9yZ2FuaXphdGlvbjE5MDcGA1UECwwwRGlyZWN0b3JhdGUtR2VuZXJhbCBmb3IgRGlnaXRhbCBTZXJ2aWNlcyAoRElHSVQpMSMwIQYDVQRhDBpMRUlYRy0yNTQ5MDBaTllBMUZMVVE5VTM5MzEcMBoGA1UECgwTRVVST1BFQU4gQ09NTUlTU0lPTjElMCMGCSqGSIb3DQEJARYWZGlnaXQtZG1vQGVjLmV1cm9wYS5ldTEcMBoGA1UEAwwTRVVST1BFQU4gQ09NTUlTU0lPTjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKWYeBA9kYARElGnHoJRNpbby44G+TSJcgHI9QtyXlYjB234hSAYyJvW+gKvoownskrogfUP6GOmQgEFZX335Y0sBwfppVemEoe9H9Aj/cpT14IqdB05V4a88ASRfR0Va1xmQJrDsBZWqZHx0EEHBctIF5BjyTMAcQybha+4AOIotp3dF/7ZA3Cu4GYbN9BuQyyqfqrjMduDzzDjVwKC17aEsLev60C1FnIJ/FVEda3lJSGilD5JyUceTaRcot1rw6gjKrOVhwP/UHfevJ3JCsQsuAzkf7ivzHzYuPPPR9Ussecwr7O95Fr4wbPYIyX2AOTlieAC7GMVXHN1/+4LH74ndvoJYEScXwmN9Skib3+G6TquOCQxvNXzHPZb95btCoSnVprCn14O3CXUTZMEKkhPuKW8dI6pR2JSGbtT+xBkcc1wYVlUnzE3d+YK5SSevUT2COwJM+AcjSoUaRTBINsD/ezDDvv7vtbF1XccaJjoCNkurzayTsMszGDvAF171LY69lNY6yK0uzrS+3c/hEHctXa5KIC3PpWrBGQ5mw73KerRvnAhzDZemVquPk1D59aJNfHoHXmy1bS52rHWYOwHH+2qbODdh8GkHwHXBzSpFit1Kg2brpavhztNaGlj6GsLFAbr8okCUJllOOLQ8Tfy9Vnn5Rq0+7VTdd8dAxg9AgMBAAGjggKaMIICljAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHNJ8UAcFAR8mhJ/+i/NXGcjGOkUMIGGBggrBgEFBQcBAQR6MHgwRgYIKwYBBQUHMAKGOmh0dHBzOi8vcWNhLWcxLmRpZ2l0YWxzaWduLnB0L0RJR0lUQUxTSUdOUVVBTElGSUVEQ0FHMS5wN2IwLgYIKwYBBQUHMAGGImh0dHBzOi8vcWNhLWcxLmRpZ2l0YWxzaWduLnB0L29jc3AwIQYDVR0RBBowGIEWZGlnaXQtZG1vQGVjLmV1cm9wYS5ldTBfBgNVHSAEWDBWMDcGCysGAQQBgcd8BAEBMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vcGtpLmRpZ2l0YWxzaWduLnB0MBAGDisGAQQBgcd8BAIBAQEGMAkGBwQAi+xAAQMwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMIG8BggrBgEFBQcBAwSBrzCBrDAVBggrBgEFBQcLAjAJBgcEAIvsSQECMAgGBgQAjkYBATAIBgYEAI5GAQQwEwYGBACORgEGMAkGBwQAjkYBBgIwagYGBACORgEFMGAwLhYoaHR0cHM6Ly9xY2EtZzEuZGlnaXRhbHNpZ24ucHQvUERTX2VuLnBkZhMCZW4wLhYoaHR0cHM6Ly9xY2EtZzEuZGlnaXRhbHNpZ24ucHQvUERTX3B0LnBkZhMCcHQwSwYDVR0fBEQwQjBAoD6gPIY6aHR0cHM6Ly9xY2EtZzEuZGlnaXRhbHNpZ24ucHQvRElHSVRBTFNJR05RVUFMSUZJRURDQUcxLmNybDAdBgNVHQ4EFgQUlO5hwcl9/63issm59r+TIHeJSZwwDgYDVR0PAQH/BAQDAgZAMA0GCSqGSIb3DQEBDQUAA4ICAQCn8qjJhTe3SsD7cB8S8kDzt+CBnJJm7bOFc9t9IU6iKntVtjPU4T+cYiPk8TnT+/w7dBphRzjZCL1sDfSJGQ5JPBw+hBPuvzEqP4xVi5i4Jhg/GpYSaa2+dkFXlKe6Sd+ii/RnwBSnfqVfNZtasj7yX+oujGau5LSUPIkQxDrMie8KjsNtlkFjQDoioGAx8b0u6WyhAuqwEacCznft20Dim3sC7XJw8GHumrnW52rUzl4sbXoTBAt8F1zPCbEbjU0oc8SbFNPIChh+9sHUorEmHIlcg30LBHihkDCx4mK8J60Jybk57D4U2RO29VsJfDmnvNxfJZxfLHEJ2tkh+AMqlJXPDlvXQ+rZ1NmLHrbXkcHOlqR3F8BakTi2Mi5AZZfkfjZjkigEStN6Enaq6gwF7EsslqEKmhSQ8XlhxWSRqljK/cnEUw+NhrvR4WuKlvYmxlCLQj6q89Hh121aUGUhL2L2WCVBjVXqux7s4mvECDzrucl5ilaVT32HO3g8qNLGD5lum53U5v/Nv68ItyHH96unztwBebmgox8giVRdzPhmPrpSfbmeNNDKj1p9SCeOvd3P9jCUvChVvH2P2ZUjc24tWe+tzclsCJi7GbKr6kjHc1jFudjehflAbm1IZAYdDNrhXamnsRVsz7iSH20eygCArlwSQ//WIQZPFrRffg==',\n subject:\n 'C=LU, OU=Certificate Profile - Qualified Certificate - Organization, OU=Directorate-General for Digital Services (DIGIT), 2.5.4.97=LEIXG-254900ZNYA1FLUQ9U393, O=EUROPEAN COMMISSION, E=digit-dmo@ec.europa.eu, CN=EUROPEAN COMMISSION',\n fingerprintSha256: 'e0a620fbb6747362bb933ac44169d676a553444716cf5f31605f12a22b8396b1',\n notAfter: '2027-11-17T10:11:46.000Z',\n },\n]\n\n/** Where this set came from, so the pin can be audited without re-running the script. */\nexport const EU_LOTL_ANCHORS_PROVENANCE = {\n /** The list the certificates were read from. */\n source: 'https://ec.europa.eu/tools/lotl/eu-lotl.xml',\n /** The Official Journal act the LOTL itself references for its signers. */\n officialJournal: 'https://eur-lex.europa.eu/eli/C/2026/1944/oj',\n /** `TSLSequenceNumber` of that list. */\n tslSequenceNumber: 390,\n /** `ListIssueDateTime` of that list. */\n listIssueDateTime: '2026-08-03T13:16:38Z',\n /** Earliest expiry in the set: refresh before this date. */\n earliestNotAfter: '2027-04-26T12:49:22.000Z',\n} as const\n","/**\n * Base exception for all trusted-list processing failures.\n */\nexport class TrustedListException extends Error {\n // NOTE: declared explicitly rather than passing `{ cause }` to `super`, as the\n // project targets ES2020 and `Error.cause` was only added in ES2022.\n public readonly cause?: unknown\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message)\n this.name = 'TrustedListException'\n this.cause = options?.cause\n }\n}\n\n/**\n * The XML could not be parsed as an ETSI TS 119 612 `TrustServiceStatusList`.\n */\nexport class TrustedListParseException extends TrustedListException {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'TrustedListParseException'\n }\n}\n\n/**\n * The trusted list's own XAdES/XMLDSig signature is missing, invalid, or does\n * not match a configured trust anchor. Callers MUST treat this as fail-closed:\n * a trusted list whose authenticity cannot be established must not be used to\n * trust credentials.\n */\nexport class TrustedListSignatureException extends TrustedListException {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'TrustedListSignatureException'\n }\n}\n","import { z } from 'zod'\n\n/**\n * A service's digital identity (TS 119 612 `ServiceDigitalIdentity`): the\n * `DigitalId` children (X509Certificate, X509SubjectName, X509SKI) that describe\n * one entity are merged here. A standard list may identify a service by subject\n * name and/or key identifier without embedding the full certificate.\n */\nexport const DigitalIdentitySchema = z.object({\n /** base64-encoded DER of the certificate, when embedded (`X509Certificate`). */\n certificate: z.string().optional(),\n /** `X509SubjectName`, when present. */\n subjectName: z.string().optional(),\n /**\n * Lowercase-hex SubjectKeyIdentifier — derived from the certificate when one\n * is embedded, otherwise from the `X509SKI` element. This is the value a\n * verifier sends to a wallet as an `aki` trusted authority (HAIP).\n */\n subjectKeyIdentifier: z.string().optional(),\n})\nexport type DigitalIdentity = z.infer<typeof DigitalIdentitySchema>\n\n/** A past status entry for a service (`ServiceHistoryInstance`). */\nexport const ServiceHistoryInstanceSchema = z.object({\n serviceTypeIdentifier: z.string().optional(),\n serviceStatus: z.string(),\n statusStartingTime: z.string().optional(),\n})\nexport type ServiceHistoryInstance = z.infer<typeof ServiceHistoryInstanceSchema>\n\n/**\n * A trust service (TSPService) entry: its type, status, digital identities,\n * qualifiers, and status history.\n */\nexport const TrustedListServiceSchema = z.object({\n /** `ServiceTypeIdentifier` URI. */\n serviceTypeIdentifier: z.string(),\n /** Current `ServiceStatus` URI. */\n serviceStatus: z.string(),\n /** Human-readable service name, if present. */\n serviceName: z.string().optional(),\n /** One entry per `ServiceDigitalIdentity`. */\n digitalIdentities: z.array(DigitalIdentitySchema),\n /** Qualifier URIs from `Qualifications/QualificationElement/Qualifiers`. */\n qualifiers: z.array(z.string()).optional(),\n /** Prior status entries from `ServiceHistory`. */\n history: z.array(ServiceHistoryInstanceSchema).optional(),\n})\nexport type TrustedListService = z.infer<typeof TrustedListServiceSchema>\n\n/** A Trust Service Provider (TSP) and the services it operates. */\nexport const TrustServiceProviderSchema = z.object({\n name: z.string().optional(),\n services: z.array(TrustedListServiceSchema),\n})\nexport type TrustServiceProvider = z.infer<typeof TrustServiceProviderSchema>\n\n/** A pointer to another trusted list (`OtherTSLPointer`), e.g. the EU LOTL. */\nexport const TrustedListPointerSchema = z.object({\n /** `TSLLocation` URL. */\n location: z.string(),\n /** Pointed-to list `TSLType`, when advertised. */\n tslType: z.string().optional(),\n /** `SchemeTerritory` (country code), when advertised. */\n schemeTerritory: z.string().optional(),\n /**\n * The pointer's `ServiceDigitalIdentities`: the certificates with which the\n * pointed-to list is signed. This is how a list distributes the trust anchors\n * of the lists it points to — the EU LOTL carries, for every national list,\n * the certificate(s) of its scheme operator, so a verifier that trusts the\n * LOTL does not need to pin each national list separately.\n */\n digitalIdentities: z.array(DigitalIdentitySchema).default([]),\n})\nexport type TrustedListPointer = z.infer<typeof TrustedListPointerSchema>\n\n/** A parsed ETSI TS 119 612 Trusted List (`TrustServiceStatusList`). */\nexport const TrustedListSchema = z.object({\n /** `TSLType` URI. */\n tslType: z.string().optional(),\n /** `SchemeOperatorName` (English name when available). */\n schemeOperatorName: z.string().optional(),\n /** `TSLSequenceNumber`. */\n sequenceNumber: z.number().optional(),\n /** `ListIssueDateTime` (ISO 8601). */\n listIssueDateTime: z.string().optional(),\n /** `NextUpdate` (ISO 8601), when present. */\n nextUpdate: z.string().optional(),\n providers: z.array(TrustServiceProviderSchema),\n /** `PointersToOtherTSL` entries (e.g. the EU LOTL). Not followed by v1. */\n pointersToOtherLists: z.array(TrustedListPointerSchema).optional(),\n})\nexport type TrustedList = z.infer<typeof TrustedListSchema>\n\n/**\n * A flattened trust anchor: one digital identity with the service context it was\n * published under. The normalized unit both certificate-chain validation and AKI\n * emission consume — the ETSI TS 119 612 counterpart of a `@owf/eudi-lote`\n * TrustedEntity service certificate.\n */\nexport const TrustAnchorSchema = z.object({\n /** base64 DER certificate, when the identity embeds one. */\n certificate: z.string().optional(),\n subjectName: z.string().optional(),\n subjectKeyIdentifier: z.string().optional(),\n serviceTypeIdentifier: z.string(),\n serviceStatus: z.string(),\n providerName: z.string().optional(),\n})\nexport type TrustAnchor = z.infer<typeof TrustAnchorSchema>\n","import type { z } from 'zod'\nimport { TrustedListParseException } from './trusted-list-exception'\nimport { type TrustedList, TrustedListSchema } from './types'\n\n/** A single validation problem, mirroring `@owf/eudi-lote`'s ValidationError. */\nexport interface ValidationError {\n path: string\n message: string\n}\n\n/** Result of a validation, mirroring `@owf/eudi-lote`'s ValidationResult. */\nexport interface ValidationResult {\n valid: boolean\n errors: ValidationError[]\n}\n\nfunction fromZodError(error: z.ZodError): ValidationError[] {\n return error.issues.map((issue) => ({\n path: issue.path.map((p) => String(p)).join('.'),\n message: issue.message,\n }))\n}\n\n/**\n * Structurally validate an object against the ETSI TS 119 612 trusted-list\n * schema (the same zod-based approach `@owf/eudi-lote` uses for TS 119 602).\n * For XML input, parse it first with `parseTrustedList` (XML → object), then\n * validate the object here.\n */\nexport function validateTrustedList(value: unknown): ValidationResult {\n const result = TrustedListSchema.safeParse(value)\n return result.success ? { valid: true, errors: [] } : { valid: false, errors: fromZodError(result.error) }\n}\n\n/**\n * Structurally validate and return the typed trusted list, throwing\n * {@link TrustedListParseException} when it does not conform to the schema.\n */\nexport function assertValidTrustedList(value: unknown): TrustedList {\n const result = TrustedListSchema.safeParse(value)\n if (!result.success) {\n const details = fromZodError(result.error)\n .map((e) => `${e.path}: ${e.message}`)\n .join('; ')\n throw new TrustedListParseException(`Invalid trusted list: ${details}`)\n }\n return result.data\n}\n\n/**\n * A profile constraint set for a trusted list: the expected `TSLType` and the\n * service type / status URIs the profile permits. The zod-based structural\n * schema ({@link validateTrustedList}) is checked first; a profile then narrows\n * a conforming list to a specific ecosystem. Rules are supplied by the caller,\n * so the library stays profile-agnostic (mirrors `@owf/eudi-lote`'s approach).\n */\nexport interface ProfileRule {\n /** Optional label used in error messages. */\n name?: string\n /** Expected `TSLType` (compared scheme-insensitively). */\n tslType: string\n /** Service type URIs the profile permits (scheme-insensitive). */\n serviceTypes: string[]\n /** Service status URIs the profile permits (scheme-insensitive). */\n serviceStatuses: string[]\n}\n\n/**\n * Compare ETSI URIs scheme-insensitively: deployed lists have published the\n * same URI over both `http` and `https`. Internal helper, not part of the\n * package's public API.\n */\nexport const stripScheme = (uri: string | undefined): string => (uri ?? '').replace(/^https?:\\/\\//, '')\n\nfunction profileErrors(trustedList: TrustedList, rule: ProfileRule): ValidationError[] {\n const label = rule.name ?? 'profile'\n const errors: ValidationError[] = []\n\n if (stripScheme(trustedList.tslType) !== stripScheme(rule.tslType)) {\n errors.push({\n path: 'tslType',\n message: `[${label}] expected TSLType ${rule.tslType}, got ${trustedList.tslType ?? 'none'}`,\n })\n }\n\n const allowedTypes = new Set(rule.serviceTypes.map(stripScheme))\n const allowedStatuses = new Set(rule.serviceStatuses.map(stripScheme))\n trustedList.providers.forEach((provider, pi) => {\n provider.services.forEach((service, si) => {\n if (!allowedTypes.has(stripScheme(service.serviceTypeIdentifier))) {\n errors.push({\n path: `providers.${pi}.services.${si}.serviceTypeIdentifier`,\n message: `[${label}] unexpected service type ${service.serviceTypeIdentifier}`,\n })\n }\n if (!allowedStatuses.has(stripScheme(service.serviceStatus))) {\n errors.push({\n path: `providers.${pi}.services.${si}.serviceStatus`,\n message: `[${label}] unexpected service status ${service.serviceStatus}`,\n })\n }\n })\n })\n\n return errors\n}\n\n/**\n * Validate that a trusted list conforms to one (or any, given several) of the\n * supplied profile rules — structural schema first, then profile-specific\n * constraints. Mirrors `@owf/eudi-lote`'s profile validation.\n */\nexport function validateTrustedListProfile(value: unknown, rule: ProfileRule | ProfileRule[]): ValidationResult {\n const structural = validateTrustedList(value)\n if (!structural.valid) return structural\n\n const trustedList = value as TrustedList\n const rules = Array.isArray(rule) ? rule : [rule]\n const perRule = rules.map((r) => profileErrors(trustedList, r))\n if (perRule.some((errors) => errors.length === 0)) {\n return { valid: true, errors: [] }\n }\n return { valid: false, errors: perRule.flat() }\n}\n","import { base64, hexEncode } from '@owf/identity-common'\nimport { SubjectKeyIdentifierExtension, X509Certificate } from '@peculiar/x509'\nimport { DOMParser, type Element } from '@xmldom/xmldom'\nimport { TrustedListParseException } from './trusted-list-exception'\nimport type {\n DigitalIdentity,\n ServiceHistoryInstance,\n TrustAnchor,\n TrustedList,\n TrustedListPointer,\n TrustedListService,\n TrustServiceProvider,\n} from './types'\nimport { assertValidTrustedList, stripScheme } from './validate'\n\nconst TSL_NS = 'http://uri.etsi.org/02231/v2#'\nconst SIE_NS = 'http://uri.etsi.org/TrstSvc/SvcInfoExt/eSigDir-1999-93-EC-TrustedList/#'\n\nfunction descendants(el: Element, name: string, ns = TSL_NS): Element[] {\n return Array.from(el.getElementsByTagNameNS(ns, name))\n}\n\nfunction firstDescendant(el: Element, name: string, ns = TSL_NS): Element | undefined {\n return descendants(el, name, ns)[0]\n}\n\nfunction textOf(el: Element | undefined): string | undefined {\n const t = el?.textContent?.trim()\n return t ? t : undefined\n}\n\n/**\n * Localized `Name`: prefer the English entry, else the first, searched only\n * among the direct `Name` children of the given parent.\n */\nfunction localizedName(parent: Element | undefined): string | undefined {\n if (!parent) return undefined\n const names = Array.from(parent.childNodes).filter(\n (n): n is Element => (n as Element).namespaceURI === TSL_NS && (n as Element).localName === 'Name'\n )\n if (names.length === 0) return undefined\n const en = names.find((n) => n.getAttribute('xml:lang') === 'en')\n return textOf(en ?? names[0])\n}\n\n/** Lowercase-hex SubjectKeyIdentifier from a certificate, best-effort. */\nfunction skiFromCertificate(certBase64: string): string | undefined {\n try {\n const cert = new X509Certificate(certBase64)\n const ext = cert.getExtension(SubjectKeyIdentifierExtension)\n if (ext?.keyId) return ext.keyId.toLowerCase()\n } catch {\n // Malformed extensions (seen in some reference certificates) — caller\n // falls back to the published X509SKI element if any.\n }\n return undefined\n}\n\n/**\n * One {@link DigitalIdentity} per `ServiceDigitalIdentity`, merging its\n * `DigitalId` children (X509Certificate / X509SubjectName / X509SKI) — a\n * standard list may identify a service without embedding the full certificate.\n */\nfunction parseDigitalIdentities(container: Element): DigitalIdentity[] {\n const identities: DigitalIdentity[] = []\n for (const sdi of descendants(container, 'ServiceDigitalIdentity')) {\n let certificate: string | undefined\n let subjectName: string | undefined\n let x509SkiHex: string | undefined\n for (const digitalId of descendants(sdi, 'DigitalId')) {\n certificate ??= textOf(firstDescendant(digitalId, 'X509Certificate'))?.replace(/\\s/g, '')\n subjectName ??= textOf(firstDescendant(digitalId, 'X509SubjectName'))\n const ski = textOf(firstDescendant(digitalId, 'X509SKI'))\n if (ski && !x509SkiHex) {\n x509SkiHex = hexEncode(base64.decode(ski.replace(/\\s/g, '')))\n }\n }\n if (!certificate && !subjectName && !x509SkiHex) continue\n identities.push({\n certificate,\n subjectName,\n subjectKeyIdentifier: certificate ? (skiFromCertificate(certificate) ?? x509SkiHex) : x509SkiHex,\n })\n }\n return identities\n}\n\nfunction parseQualifiers(serviceInfo: Element): string[] | undefined {\n const uris = descendants(serviceInfo, 'Qualifier', SIE_NS)\n .map((q) => q.getAttribute('uri') ?? '')\n .filter((u) => u.length > 0)\n return uris.length > 0 ? uris : undefined\n}\n\nfunction parseHistory(service: Element): ServiceHistoryInstance[] | undefined {\n const history: ServiceHistoryInstance[] = []\n for (const instance of descendants(service, 'ServiceHistoryInstance')) {\n const serviceStatus = textOf(firstDescendant(instance, 'ServiceStatus'))\n if (!serviceStatus) continue\n history.push({\n serviceTypeIdentifier: textOf(firstDescendant(instance, 'ServiceTypeIdentifier')),\n serviceStatus,\n statusStartingTime: textOf(firstDescendant(instance, 'StatusStartingTime')),\n })\n }\n return history.length > 0 ? history : undefined\n}\n\nfunction parsePointers(schemeInfo: Element): TrustedListPointer[] | undefined {\n const pointers: TrustedListPointer[] = []\n for (const pointer of descendants(schemeInfo, 'OtherTSLPointer')) {\n const location = textOf(firstDescendant(pointer, 'TSLLocation'))\n if (!location) continue\n pointers.push({\n location,\n tslType: textOf(firstDescendant(pointer, 'TSLType')),\n schemeTerritory: textOf(firstDescendant(pointer, 'SchemeTerritory')),\n // The pointer's own ServiceDigitalIdentities: the certificate(s) the\n // pointed-to list is signed with.\n digitalIdentities: parseDigitalIdentities(pointer),\n })\n }\n return pointers.length > 0 ? pointers : undefined\n}\n\n/**\n * Parse an ETSI TS 119 612 `TrustServiceStatusList` XML into a normalized\n * {@link TrustedList}. This does NOT verify the list signature — call\n * {@link verifyTrustedListSignature} first (or use {@link loadTrustedList}).\n */\nexport function parseTrustedList(xml: string): TrustedList {\n const doc = new DOMParser().parseFromString(xml, 'application/xml')\n const root: Element | null = doc.documentElement\n if (root?.localName !== 'TrustServiceStatusList') {\n throw new TrustedListParseException('Root element is not a TS 119 612 TrustServiceStatusList')\n }\n\n const schemeInfo = firstDescendant(root, 'SchemeInformation')\n const sequenceText = textOf(schemeInfo && firstDescendant(schemeInfo, 'TSLSequenceNumber'))\n const nextUpdate = schemeInfo && firstDescendant(schemeInfo, 'NextUpdate')\n\n const providers: TrustServiceProvider[] = []\n for (const tsp of descendants(root, 'TrustServiceProvider')) {\n const services: TrustedListService[] = []\n for (const service of descendants(tsp, 'TSPService')) {\n const info = firstDescendant(service, 'ServiceInformation')\n if (!info) continue\n const serviceTypeIdentifier = textOf(firstDescendant(info, 'ServiceTypeIdentifier'))\n const serviceStatus = textOf(firstDescendant(info, 'ServiceStatus'))\n if (!serviceTypeIdentifier || !serviceStatus) continue\n services.push({\n serviceTypeIdentifier,\n serviceStatus,\n serviceName: localizedName(firstDescendant(info, 'ServiceName')),\n digitalIdentities: parseDigitalIdentities(info),\n qualifiers: parseQualifiers(info),\n history: parseHistory(service),\n })\n }\n providers.push({\n name: localizedName(firstDescendant(tsp, 'TSPName')),\n services,\n })\n }\n\n // Validate the constructed object through the zod schema, so parsing is\n // schema-driven (the same approach @owf/eudi-lote uses for TS 119 602 JSON).\n return assertValidTrustedList({\n tslType: textOf(schemeInfo && firstDescendant(schemeInfo, 'TSLType')),\n schemeOperatorName: localizedName(schemeInfo && firstDescendant(schemeInfo, 'SchemeOperatorName')),\n sequenceNumber: sequenceText ? Number(sequenceText) : undefined,\n listIssueDateTime: textOf(schemeInfo && firstDescendant(schemeInfo, 'ListIssueDateTime')),\n nextUpdate: textOf(nextUpdate && firstDescendant(nextUpdate, 'dateTime')),\n providers,\n pointersToOtherLists: schemeInfo ? parsePointers(schemeInfo) : undefined,\n })\n}\n\n/** Selects `PointersToOtherTSL` entries in {@link getPointerSigningCertificates}. */\nexport interface TrustedListPointerFilter {\n /** `SchemeTerritory` of the pointed-to list (e.g. `ES`), case-insensitive. */\n schemeTerritory?: string\n /** `TSLType` of the pointed-to list, compared scheme-insensitively. */\n tslType?: string\n /** Exact `TSLLocation` URL of the pointed-to list. */\n location?: string\n}\n\n/**\n * The DER-encoded certificates a list publishes for the lists it points to —\n * i.e. the trust anchors with which those lists are signed, ready to be passed\n * as `trustAnchors` to `verifyTrustedListSignature`.\n *\n * This is the mechanism by which a trusted list distributes trust downwards: a\n * verifier that has established trust in one list (for the EU LOTL, by pinning\n * its signing certificates out of band) obtains the anchors of every list it\n * points to without pinning them individually.\n *\n * ```ts\n * const lotl = await loadTrustedList(lotlXml, { trustAnchors: getEuLotlTrustAnchors() })\n * const esAnchors = getPointerSigningCertificates(lotl, { schemeTerritory: 'ES' })\n * const esList = await loadTrustedList(esXml, { trustAnchors: esAnchors })\n * ```\n *\n * Passing `{ tslType: TSLType.EUlistofthelists }` returns the LOTL's own\n * currently published signing certificates (from its self-pointer), which is\n * how a deployment refreshes its pinned set as the scheme operator rotates keys.\n */\nexport function getPointerSigningCertificates(\n trustedList: TrustedList,\n filter: TrustedListPointerFilter = {}\n): Uint8Array[] {\n const certificates: Uint8Array[] = []\n const seen = new Set<string>()\n for (const pointer of trustedList.pointersToOtherLists ?? []) {\n if (filter.location && pointer.location !== filter.location) continue\n if (filter.schemeTerritory && pointer.schemeTerritory?.toUpperCase() !== filter.schemeTerritory.toUpperCase()) {\n continue\n }\n if (filter.tslType && stripScheme(pointer.tslType) !== stripScheme(filter.tslType)) continue\n for (const identity of pointer.digitalIdentities) {\n if (!identity.certificate || seen.has(identity.certificate)) continue\n seen.add(identity.certificate)\n certificates.push(base64.decode(identity.certificate))\n }\n }\n return certificates\n}\n\nexport interface TrustAnchorFilter {\n /**\n * When set, only include services whose `serviceStatus` is in this list\n * (e.g. `ACTIVE_SERVICE_STATUSES`). Withdrawn/deprecated services are\n * excluded.\n */\n serviceStatus?: string[]\n /** When set, only include services whose `serviceTypeIdentifier` matches. */\n serviceTypeIdentifier?: string[]\n /**\n * When true, only include anchors that embed an X.509 certificate (i.e. the\n * ones usable for certificate-chain validation). Defaults to false, which\n * also returns SubjectName/SKI-only identities (useful for AKI queries).\n */\n requireCertificate?: boolean\n}\n\n/**\n * Flatten a {@link TrustedList} into individual {@link TrustAnchor} entries —\n * the normalized unit consumed by certificate-chain validation and AKI\n * emission.\n */\nexport function getTrustAnchors(trustedList: TrustedList, filter: TrustAnchorFilter = {}): TrustAnchor[] {\n const anchors: TrustAnchor[] = []\n for (const provider of trustedList.providers) {\n for (const service of provider.services) {\n if (filter.serviceStatus && !filter.serviceStatus.includes(service.serviceStatus)) {\n continue\n }\n if (filter.serviceTypeIdentifier && !filter.serviceTypeIdentifier.includes(service.serviceTypeIdentifier)) {\n continue\n }\n for (const identity of service.digitalIdentities) {\n if (filter.requireCertificate && !identity.certificate) {\n continue\n }\n anchors.push({\n certificate: identity.certificate,\n subjectName: identity.subjectName,\n subjectKeyIdentifier: identity.subjectKeyIdentifier,\n serviceTypeIdentifier: service.serviceTypeIdentifier,\n serviceStatus: service.serviceStatus,\n providerName: provider.name,\n })\n }\n }\n }\n return anchors\n}\n","import { ServiceStatus, ServiceType, TSLType } from './constants'\nimport type { ProfileRule } from './validate'\n\n/** Every standard TS 119 612 service status (clause 5.5.4). */\nconst ALL_SERVICE_STATUSES: string[] = Object.values(ServiceStatus)\n\n/** The standard qualified `ServiceTypeIdentifier` values (Annex D). */\nconst QUALIFIED_SERVICE_TYPES: string[] = Object.values(ServiceType)\n\n/**\n * Ready-made {@link ProfileRule}s for common ETSI ecosystems, so callers don't\n * have to hand-write the URIs. The engine ({@link validateTrustedListProfile})\n * stays profile-agnostic; these are just convenience constants you pass into it.\n *\n * A profile is an allowlist: the structural schema is checked first, then the\n * list's `TSLType` must match and every service's type/status must be permitted.\n * That fits homogeneous, curated lists well (e.g. Age Verification). For a full\n * eIDAS national list — which legitimately carries withdrawn/ceased services and\n * a broad mix of qualified service types — {@link euGeneric} therefore permits\n * all standard ETSI statuses and qualified service types: it asserts \"this is a\n * well-formed EU generic list using standard ETSI URIs\", not \"only currently\n * active CAs\". Narrow further with your own {@link ProfileRule} when you need to.\n */\nexport const TrustedListProfiles = {\n /**\n * EU List of Trusted Lists (LOTL). Its `TSLType` is `EUlistofthelists` and it\n * carries pointers to national lists rather than trust-service providers, so\n * no service type/status is permitted (a conforming LOTL has no TSP services).\n */\n euLotl: {\n name: 'eu-lotl',\n tslType: TSLType.EUlistofthelists,\n serviceTypes: [],\n serviceStatuses: [],\n },\n /**\n * A generic EU (eIDAS national) trusted list: `TSLType` `EUgeneric`, any\n * standard qualified service type, any standard service status (including\n * withdrawn/ceased entries that national lists retain for history).\n */\n euGeneric: {\n name: 'eu-generic',\n tslType: TSLType.EUgeneric,\n serviceTypes: QUALIFIED_SERVICE_TYPES,\n serviceStatuses: ALL_SERVICE_STATUSES,\n },\n /**\n * EU Age Verification trusted list, per the European Commission's \"AV Trusted\n * List Specifications\" (DIGIT.B.3). The `TSLType` (clause 5.3.3), the single\n * Proof of Age Attestation service type (`paa`, clause 5.5.1) and the two\n * permitted service statuses (clause 5.5.4) are fixed by that specification —\n * which states the statuses \"may be used to the exclusion of any other\", so\n * the allowlist model captures the AV profile exactly. Deployed lists have\n * used `https` for the `TSLType`; the profile compares scheme-insensitively.\n */\n ageVerification: {\n name: 'eu-age-verification',\n tslType: 'http://trust.tech.ec.europa.eu/lists/age-verification/tsl-type',\n serviceTypes: ['http://trust.tech.ec.europa.eu/lists/age-verification/service-type/paa'],\n serviceStatuses: [\n 'http://trust.tech.ec.europa.eu/lists/age-verification/service-status/recognized',\n 'http://trust.tech.ec.europa.eu/lists/age-verification/service-status/deprecated',\n ],\n },\n} satisfies Record<string, ProfileRule>\n","import { base64, compareBytes } from '@owf/identity-common'\nimport { DOMParser, XMLSerializer } from '@xmldom/xmldom'\nimport * as xadesjs from 'xadesjs'\nimport * as xpath from 'xpath'\nimport { TrustedListSignatureException } from './trusted-list-exception'\n\nconst XMLDSIG_NS = 'http://www.w3.org/2000/09/xmldsig#'\n\nlet nodeDependenciesInitialized = false\nlet installedCrypto: Crypto | undefined\n\n/**\n * Outside the browser, xml-core resolves DOM/XPath implementations through\n * `setNodeDependencies`. Set lazily and once, so importing this package has no\n * side effects until a signature is actually processed.\n */\nfunction ensureNodeDependencies(): void {\n if (nodeDependenciesInitialized) return\n xadesjs.setNodeDependencies({ DOMParser, XMLSerializer, xpath })\n nodeDependenciesInitialized = true\n}\n\n/**\n * Install the WebCrypto implementation used to verify trusted list signatures\n * (\"bring your own crypto\"), for callers that must route verification through a\n * reviewed or policy-constrained engine. Call it once during start-up, before\n * verifying; without it, the global Web Crypto API (`globalThis.crypto`,\n * available in Node >= 20 and browsers) is used.\n *\n * Process-wide by necessity, not by design: xadesjs exposes a single global\n * crypto engine rather than a per-call context\n * (see {@link https://github.com/PeculiarVentures/xmldsigjs/issues/119}).\n * A per-invocation option would look isolated while still swapping that global,\n * so concurrent verifications with different engines would race; it is\n * deliberately not offered. Should upstream gain per-call crypto, accepting it\n * as a verification option is an additive, non-breaking change.\n */\nexport function setTrustedListCrypto(crypto: Crypto): void {\n ensureNodeDependencies()\n xadesjs.Application.setEngine('eudi-tl', crypto)\n installedCrypto = crypto\n}\n\n/**\n * Make sure a crypto engine is installed before verifying. A caller-installed\n * engine is never replaced — falling back to `globalThis.crypto` on every call\n * that does not opt in would silently undo {@link setTrustedListCrypto}.\n */\nfunction ensureXmlSignatureEngine(): void {\n ensureNodeDependencies()\n if (!installedCrypto) setTrustedListCrypto(globalThis.crypto)\n}\n\nexport interface VerifyTrustedListOptions {\n /**\n * DER-encoded certificates the trusted list's signer certificate must match.\n * When provided, verification fails closed unless the embedded signer\n * certificate equals one of these anchors — establishing that the list was\n * signed by the expected scheme operator, not merely by *some* key.\n *\n * When omitted, only the cryptographic validity of the enveloped signature\n * is checked; that proves integrity, NOT trust. Production callers should\n * always pin the scheme operator certificate(s).\n */\n trustAnchors?: Uint8Array[]\n}\n\nexport interface VerifyTrustedListResult {\n /** base64-encoded DER of the signer certificate from the signature KeyInfo. */\n signerCertificateBase64: string\n}\n\n/**\n * Verify the enveloped XAdES/XMLDSig signature of an ETSI TS 119 612 Trusted\n * List. Throws {@link TrustedListSignatureException} when the signature is\n * missing, invalid, or (with `trustAnchors`) not signed by a pinned scheme\n * operator.\n *\n * Verified against a standard eIDAS national trusted list (RSA-SHA512,\n * exclusive C14N, XAdES SignedProperties).\n *\n * Verification runs on the global Web Crypto API unless another implementation\n * was installed with {@link setTrustedListCrypto}.\n */\nexport async function verifyTrustedListSignature(\n xml: string,\n options: VerifyTrustedListOptions = {}\n): Promise<VerifyTrustedListResult> {\n ensureXmlSignatureEngine()\n\n const doc = new DOMParser().parseFromString(xml, 'application/xml')\n const signatures = doc.getElementsByTagNameNS(XMLDSIG_NS, 'Signature')\n if (signatures.length === 0) {\n throw new TrustedListSignatureException('No ds:Signature found in the trusted list')\n }\n\n // xadesjs is typed against the lib.dom DOM; @xmldom implements the same\n // shape at runtime, so bridge the two nominal types at this boundary only.\n const signedXml = new xadesjs.SignedXml(doc as unknown as Document)\n signedXml.LoadXml(signatures[0] as unknown as Element)\n\n let valid: boolean\n try {\n valid = await signedXml.Verify()\n } catch (error) {\n throw new TrustedListSignatureException(\n `Trusted list signature could not be verified: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n )\n }\n if (!valid) {\n throw new TrustedListSignatureException('Trusted list signature is invalid')\n }\n\n // The signature KeyInfo carries the signer certificate (ds:X509Certificate,\n // namespace-scoped so it never picks up service certificates).\n const signerCertEl = signatures[0].getElementsByTagNameNS(XMLDSIG_NS, 'X509Certificate')[0]\n if (!signerCertEl?.textContent) {\n throw new TrustedListSignatureException('Trusted list signature has no X509Certificate in KeyInfo')\n }\n const signerCertificateBase64 = signerCertEl.textContent.replace(/\\s/g, '')\n\n if (options.trustAnchors && options.trustAnchors.length > 0) {\n const signerDer = base64.decode(signerCertificateBase64)\n const trusted = options.trustAnchors.some((anchor) => compareBytes(anchor, signerDer))\n if (!trusted) {\n throw new TrustedListSignatureException(\n 'Trusted list signer certificate is not among the configured trust anchors'\n )\n }\n }\n\n return { signerCertificateBase64 }\n}\n","import { base64 } from '@owf/identity-common'\nimport { EU_LOTL_SIGNING_CERTIFICATES } from './eu-lotl-anchors'\nimport { parseTrustedList } from './parse'\nimport { TrustedListProfiles } from './profiles'\nimport { TrustedListParseException } from './trusted-list-exception'\nimport type { TrustedList } from './types'\nimport { validateTrustedListProfile } from './validate'\nimport { type VerifyTrustedListOptions, type VerifyTrustedListResult, verifyTrustedListSignature } from './verify'\n\n/**\n * The LOTL signing certificates shipped with this package, as DER bytes ready\n * to pass as `trustAnchors`.\n *\n * This pinned set is the root of the eIDAS trusted-list hierarchy and cannot be\n * bootstrapped from the LOTL itself — a forged list would carry a forged\n * self-pointer. It is published by the European Commission in the Official\n * Journal; see {@link EU_LOTL_ANCHORS_PROVENANCE} for the exact act, list issue\n * and expiry of the shipped set.\n *\n * Certificates rotate (historically every 6–24 months), so a deployment has\n * three ways to stay current without waiting for a release of this package:\n *\n * 1. pass its own `trustAnchors`, e.g. from configuration;\n * 2. after verifying a LOTL, read the currently published set from its own\n * self-pointer with `getPointerSigningCertificates(lotl, { tslType:\n * TSLType.EUlistofthelists })` and persist it — rotation is announced in a\n * list still signed by the previous generation of keys;\n * 3. follow the pivot LOTLs advertised in the list's `SchemeInformationURI`\n * when the pinned set has fallen behind entirely.\n */\nexport function getEuLotlTrustAnchors(): Uint8Array[] {\n return EU_LOTL_SIGNING_CERTIFICATES.map((entry) => base64.decode(entry.certificate))\n}\n\n/**\n * Verify the signature of the EU List of Trusted Lists against the shipped\n * signing certificates. Identical to {@link verifyTrustedListSignature} except\n * that `trustAnchors` defaults to {@link getEuLotlTrustAnchors} instead of to\n * \"integrity only\" — pass your own to override.\n */\nexport function verifyEuLotlSignature(\n xml: string,\n options: VerifyTrustedListOptions = {}\n): Promise<VerifyTrustedListResult> {\n return verifyTrustedListSignature(xml, { ...options, trustAnchors: options.trustAnchors ?? getEuLotlTrustAnchors() })\n}\n\n/**\n * Verify, parse and profile-check the EU List of Trusted Lists in one step: the\n * safe entry point for the top of the hierarchy. The returned list carries the\n * `PointersToOtherTSL` entries from which national list anchors are derived\n * with `getPointerSigningCertificates`.\n */\nexport async function loadEuLotl(xml: string, options: VerifyTrustedListOptions = {}): Promise<TrustedList> {\n await verifyEuLotlSignature(xml, options)\n const lotl = parseTrustedList(xml)\n const profile = validateTrustedListProfile(lotl, TrustedListProfiles.euLotl)\n if (!profile.valid) {\n const details = profile.errors.map((error) => `${error.path}: ${error.message}`).join('; ')\n throw new TrustedListParseException(`Not a conforming EU List of Trusted Lists: ${details}`)\n }\n return lotl\n}\n","/**\n * @owf/eudi-tl\n *\n * Parse and verify ETSI TS 119 612 XML Trusted Lists and expose normalized\n * trust anchors. Companion to `@owf/eudi-lote` (ETSI TS 119 602, JSON): both\n * resolve to the same normalized notion of a trust anchor, so a verifier can\n * consume either format and, for example, derive AKIs to send to a wallet.\n */\nexport {\n ACTIVE_SERVICE_STATUSES,\n ServiceStatus,\n ServiceType,\n TSLType,\n} from './constants'\nexport {\n getEuLotlTrustAnchors,\n loadEuLotl,\n verifyEuLotlSignature,\n} from './eu-lotl'\nexport {\n EU_LOTL_ANCHORS_PROVENANCE,\n EU_LOTL_SIGNING_CERTIFICATES,\n type EuLotlSigningCertificate,\n} from './eu-lotl-anchors'\nexport {\n getPointerSigningCertificates,\n getTrustAnchors,\n parseTrustedList,\n type TrustAnchorFilter,\n type TrustedListPointerFilter,\n} from './parse'\nexport { TrustedListProfiles } from './profiles'\nexport {\n TrustedListException,\n TrustedListParseException,\n TrustedListSignatureException,\n} from './trusted-list-exception'\nexport {\n type DigitalIdentity,\n DigitalIdentitySchema,\n type ServiceHistoryInstance,\n ServiceHistoryInstanceSchema,\n type TrustAnchor,\n TrustAnchorSchema,\n type TrustedList,\n type TrustedListPointer,\n TrustedListPointerSchema,\n TrustedListSchema,\n type TrustedListService,\n TrustedListServiceSchema,\n type TrustServiceProvider,\n TrustServiceProviderSchema,\n} from './types'\nexport {\n assertValidTrustedList,\n type ProfileRule,\n type ValidationError,\n type ValidationResult,\n validateTrustedList,\n validateTrustedListProfile,\n} from './validate'\nexport {\n setTrustedListCrypto,\n type VerifyTrustedListOptions,\n type VerifyTrustedListResult,\n verifyTrustedListSignature,\n} from './verify'\n\nimport { parseTrustedList } from './parse'\nimport type { TrustedList } from './types'\nimport { type VerifyTrustedListOptions, verifyTrustedListSignature } from './verify'\n\n/**\n * Verify the trusted list signature and, only if it is valid, parse it. This is\n * the safe entry point: it never returns a {@link TrustedList} whose\n * authenticity has not been established.\n */\nexport async function loadTrustedList(xml: string, options: VerifyTrustedListOptions = {}): Promise<TrustedList> {\n await verifyTrustedListSignature(xml, options)\n return parseTrustedList(xml)\n}\n"],"mappings":"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"}