@pagopa/io-react-native-wallet 2.0.0-next.1 → 2.0.0-next.3

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.
Files changed (174) hide show
  1. package/lib/commonjs/credential/issuance/02-evaluate-issuer-trust.js +2 -2
  2. package/lib/commonjs/credential/issuance/02-evaluate-issuer-trust.js.map +1 -1
  3. package/lib/commonjs/credential/issuance/03-start-user-authorization.js +38 -24
  4. package/lib/commonjs/credential/issuance/03-start-user-authorization.js.map +1 -1
  5. package/lib/commonjs/credential/issuance/05-authorize-access.js +6 -10
  6. package/lib/commonjs/credential/issuance/05-authorize-access.js.map +1 -1
  7. package/lib/commonjs/credential/issuance/06-obtain-credential.js +43 -11
  8. package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
  9. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +51 -48
  10. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  11. package/lib/commonjs/credential/issuance/README.md +34 -13
  12. package/lib/commonjs/credential/issuance/const.js +1 -1
  13. package/lib/commonjs/credential/issuance/types.js +16 -10
  14. package/lib/commonjs/credential/issuance/types.js.map +1 -1
  15. package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js +2 -2
  16. package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
  17. package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -1
  18. package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +4 -4
  19. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +3 -3
  20. package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
  21. package/lib/commonjs/credential/status/README.md +0 -1
  22. package/lib/commonjs/sd-jwt/__test__/index.test.js +11 -15
  23. package/lib/commonjs/sd-jwt/__test__/index.test.js.map +1 -1
  24. package/lib/commonjs/sd-jwt/__test__/types.test.js +5 -2
  25. package/lib/commonjs/sd-jwt/__test__/types.test.js.map +1 -1
  26. package/lib/commonjs/sd-jwt/__test__/utils.test.js +37 -0
  27. package/lib/commonjs/sd-jwt/__test__/utils.test.js.map +1 -0
  28. package/lib/commonjs/sd-jwt/index.js +20 -0
  29. package/lib/commonjs/sd-jwt/index.js.map +1 -1
  30. package/lib/commonjs/sd-jwt/types.js +51 -4
  31. package/lib/commonjs/sd-jwt/types.js.map +1 -1
  32. package/lib/commonjs/sd-jwt/utils.js +64 -0
  33. package/lib/commonjs/sd-jwt/utils.js.map +1 -0
  34. package/lib/commonjs/trust/build-chain.js +252 -0
  35. package/lib/commonjs/trust/build-chain.js.map +1 -0
  36. package/lib/commonjs/trust/index.js +11 -282
  37. package/lib/commonjs/trust/index.js.map +1 -1
  38. package/lib/commonjs/trust/types.js +18 -13
  39. package/lib/commonjs/trust/types.js.map +1 -1
  40. package/lib/commonjs/trust/{chain.js → verify-chain.js} +40 -5
  41. package/lib/commonjs/trust/verify-chain.js.map +1 -0
  42. package/lib/commonjs/utils/errors.js.map +1 -1
  43. package/lib/commonjs/utils/par.js +32 -22
  44. package/lib/commonjs/utils/par.js.map +1 -1
  45. package/lib/commonjs/utils/pop.js +1 -1
  46. package/lib/commonjs/utils/pop.js.map +1 -1
  47. package/lib/commonjs/wallet-instance-attestation/types.js +5 -1
  48. package/lib/commonjs/wallet-instance-attestation/types.js.map +1 -1
  49. package/lib/module/credential/issuance/02-evaluate-issuer-trust.js +1 -1
  50. package/lib/module/credential/issuance/02-evaluate-issuer-trust.js.map +1 -1
  51. package/lib/module/credential/issuance/03-start-user-authorization.js +38 -24
  52. package/lib/module/credential/issuance/03-start-user-authorization.js.map +1 -1
  53. package/lib/module/credential/issuance/05-authorize-access.js +6 -10
  54. package/lib/module/credential/issuance/05-authorize-access.js.map +1 -1
  55. package/lib/module/credential/issuance/06-obtain-credential.js +44 -12
  56. package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
  57. package/lib/module/credential/issuance/07-verify-and-parse-credential.js +51 -48
  58. package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  59. package/lib/module/credential/issuance/README.md +34 -13
  60. package/lib/module/credential/issuance/const.js +1 -1
  61. package/lib/module/credential/issuance/types.js +12 -8
  62. package/lib/module/credential/issuance/types.js.map +1 -1
  63. package/lib/module/credential/presentation/02-evaluate-rp-trust.js +1 -1
  64. package/lib/module/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
  65. package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -1
  66. package/lib/module/credential/presentation/07-evaluate-dcql-query.js +4 -4
  67. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +3 -3
  68. package/lib/module/credential/presentation/08-send-authorization-response.js +1 -1
  69. package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
  70. package/lib/module/credential/status/README.md +0 -1
  71. package/lib/module/sd-jwt/__test__/index.test.js +11 -16
  72. package/lib/module/sd-jwt/__test__/index.test.js.map +1 -1
  73. package/lib/module/sd-jwt/__test__/types.test.js +5 -2
  74. package/lib/module/sd-jwt/__test__/types.test.js.map +1 -1
  75. package/lib/module/sd-jwt/__test__/utils.test.js +35 -0
  76. package/lib/module/sd-jwt/__test__/utils.test.js.map +1 -0
  77. package/lib/module/sd-jwt/index.js +1 -0
  78. package/lib/module/sd-jwt/index.js.map +1 -1
  79. package/lib/module/sd-jwt/types.js +50 -3
  80. package/lib/module/sd-jwt/types.js.map +1 -1
  81. package/lib/module/sd-jwt/utils.js +57 -0
  82. package/lib/module/sd-jwt/utils.js.map +1 -0
  83. package/lib/module/trust/build-chain.js +235 -0
  84. package/lib/module/trust/build-chain.js.map +1 -0
  85. package/lib/module/trust/index.js +5 -268
  86. package/lib/module/trust/index.js.map +1 -1
  87. package/lib/module/trust/types.js +18 -13
  88. package/lib/module/trust/types.js.map +1 -1
  89. package/lib/module/trust/{chain.js → verify-chain.js} +36 -2
  90. package/lib/module/trust/verify-chain.js.map +1 -0
  91. package/lib/module/utils/errors.js +1 -1
  92. package/lib/module/utils/errors.js.map +1 -1
  93. package/lib/module/utils/par.js +29 -20
  94. package/lib/module/utils/par.js.map +1 -1
  95. package/lib/module/utils/pop.js +1 -1
  96. package/lib/module/utils/pop.js.map +1 -1
  97. package/lib/module/wallet-instance-attestation/types.js +5 -1
  98. package/lib/module/wallet-instance-attestation/types.js.map +1 -1
  99. package/lib/typescript/client/generated/wallet-provider.d.ts +12 -12
  100. package/lib/typescript/credential/issuance/01-start-flow.d.ts +2 -2
  101. package/lib/typescript/credential/issuance/01-start-flow.d.ts.map +1 -1
  102. package/lib/typescript/credential/issuance/02-evaluate-issuer-trust.d.ts.map +1 -1
  103. package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts +7 -6
  104. package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts.map +1 -1
  105. package/lib/typescript/credential/issuance/05-authorize-access.d.ts.map +1 -1
  106. package/lib/typescript/credential/issuance/06-obtain-credential.d.ts +10 -5
  107. package/lib/typescript/credential/issuance/06-obtain-credential.d.ts.map +1 -1
  108. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts +3 -2
  109. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
  110. package/lib/typescript/credential/issuance/const.d.ts +1 -1
  111. package/lib/typescript/credential/issuance/types.d.ts +46 -26
  112. package/lib/typescript/credential/issuance/types.d.ts.map +1 -1
  113. package/lib/typescript/credential/presentation/02-evaluate-rp-trust.d.ts.map +1 -1
  114. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +1 -1
  115. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -1
  116. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +2 -2
  117. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -1
  118. package/lib/typescript/credential/presentation/types.d.ts +4 -4
  119. package/lib/typescript/pid/sd-jwt/types.d.ts +7 -7
  120. package/lib/typescript/sd-jwt/__test__/utils.test.d.ts +2 -0
  121. package/lib/typescript/sd-jwt/__test__/utils.test.d.ts.map +1 -0
  122. package/lib/typescript/sd-jwt/index.d.ts +21 -8
  123. package/lib/typescript/sd-jwt/index.d.ts.map +1 -1
  124. package/lib/typescript/sd-jwt/types.d.ts +194 -12
  125. package/lib/typescript/sd-jwt/types.d.ts.map +1 -1
  126. package/lib/typescript/sd-jwt/utils.d.ts +18 -0
  127. package/lib/typescript/sd-jwt/utils.d.ts.map +1 -0
  128. package/lib/typescript/trust/build-chain.d.ts +1300 -0
  129. package/lib/typescript/trust/build-chain.d.ts.map +1 -0
  130. package/lib/typescript/trust/index.d.ts +5 -1301
  131. package/lib/typescript/trust/index.d.ts.map +1 -1
  132. package/lib/typescript/trust/types.d.ts +788 -624
  133. package/lib/typescript/trust/types.d.ts.map +1 -1
  134. package/lib/typescript/trust/{chain.d.ts → verify-chain.d.ts} +17 -1
  135. package/lib/typescript/trust/verify-chain.d.ts.map +1 -0
  136. package/lib/typescript/utils/errors.d.ts +2 -2
  137. package/lib/typescript/utils/errors.d.ts.map +1 -1
  138. package/lib/typescript/utils/par.d.ts +29 -13
  139. package/lib/typescript/utils/par.d.ts.map +1 -1
  140. package/lib/typescript/wallet-instance-attestation/types.d.ts +9 -9
  141. package/lib/typescript/wallet-instance-attestation/types.d.ts.map +1 -1
  142. package/package.json +1 -1
  143. package/src/credential/issuance/01-start-flow.ts +2 -2
  144. package/src/credential/issuance/02-evaluate-issuer-trust.ts +1 -1
  145. package/src/credential/issuance/03-start-user-authorization.ts +57 -38
  146. package/src/credential/issuance/05-authorize-access.ts +5 -11
  147. package/src/credential/issuance/06-obtain-credential.ts +53 -23
  148. package/src/credential/issuance/07-verify-and-parse-credential.ts +54 -62
  149. package/src/credential/issuance/README.md +34 -13
  150. package/src/credential/issuance/const.ts +1 -1
  151. package/src/credential/issuance/types.ts +18 -8
  152. package/src/credential/presentation/02-evaluate-rp-trust.ts +1 -1
  153. package/src/credential/presentation/05-verify-request-object.ts +1 -1
  154. package/src/credential/presentation/07-evaluate-dcql-query.ts +4 -4
  155. package/src/credential/presentation/07-evaluate-input-descriptor.ts +3 -3
  156. package/src/credential/presentation/08-send-authorization-response.ts +4 -4
  157. package/src/credential/status/README.md +0 -1
  158. package/src/sd-jwt/__test__/index.test.ts +8 -29
  159. package/src/sd-jwt/__test__/types.test.ts +6 -2
  160. package/src/sd-jwt/__test__/utils.test.ts +37 -0
  161. package/src/sd-jwt/index.ts +2 -0
  162. package/src/sd-jwt/types.ts +49 -2
  163. package/src/sd-jwt/utils.ts +73 -0
  164. package/src/trust/build-chain.ts +395 -0
  165. package/src/trust/index.ts +5 -442
  166. package/src/trust/types.ts +23 -17
  167. package/src/trust/{chain.ts → verify-chain.ts} +41 -1
  168. package/src/utils/errors.ts +4 -4
  169. package/src/utils/par.ts +37 -21
  170. package/src/utils/pop.ts +1 -1
  171. package/src/wallet-instance-attestation/types.ts +3 -1
  172. package/lib/commonjs/trust/chain.js.map +0 -1
  173. package/lib/module/trust/chain.js.map +0 -1
  174. package/lib/typescript/trust/chain.d.ts.map +0 -1
@@ -1,443 +1,6 @@
1
- import { decode, verify } from "./utils";
2
- import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
3
- import {
4
- CredentialIssuerEntityConfiguration,
5
- EntityConfiguration,
6
- EntityStatement,
7
- FederationListResponse,
8
- RelyingPartyEntityConfiguration,
9
- TrustAnchorEntityConfiguration,
10
- WalletProviderEntityConfiguration,
11
- } from "./types";
12
- import { renewTrustChain, validateTrustChain } from "./chain";
13
- import { hasStatusOrThrow } from "../utils/misc";
14
- import type { JWK } from "../utils/jwk";
15
- import {
16
- BuildTrustChainError,
17
- FederationListParseError,
18
- MissingFederationFetchEndpointError,
19
- RelyingPartyNotAuthorizedError,
20
- TrustAnchorKidMissingError,
21
- } from "./errors";
22
- import type { X509CertificateOptions } from "@pagopa/io-react-native-crypto";
1
+ import * as Build from "./build-chain";
2
+ import * as Verify from "./verify-chain";
3
+ import * as Errors from "./errors";
4
+ import * as Types from "./types";
23
5
 
24
- export type {
25
- WalletProviderEntityConfiguration,
26
- TrustAnchorEntityConfiguration,
27
- CredentialIssuerEntityConfiguration,
28
- RelyingPartyEntityConfiguration,
29
- EntityConfiguration,
30
- EntityStatement,
31
- };
32
-
33
- /**
34
- * Verify a given trust chain is actually valid.
35
- * It can handle fast chain renewal, which means we try to fetch a fresh version of each statement.
36
- *
37
- * @param trustAnchorEntity The entity configuration of the known trust anchor
38
- * @param chain The chain of statements to be validated
39
- * @param x509Options Options for the verification process
40
- * @param appFetch (optional) fetch api implementation
41
- * @param renewOnFail Whether to attempt to renew the trust chain if the initial validation fails
42
- * @returns The result of the chain validation
43
- * @throws {FederationError} If the chain is not valid
44
- */
45
- export async function verifyTrustChain(
46
- trustAnchorEntity: TrustAnchorEntityConfiguration,
47
- chain: string[],
48
- x509Options: X509CertificateOptions = {
49
- connectTimeout: 10000,
50
- readTimeout: 10000,
51
- requireCrl: true,
52
- },
53
- {
54
- appFetch = fetch,
55
- renewOnFail = true,
56
- }: { appFetch?: GlobalFetch["fetch"]; renewOnFail?: boolean } = {}
57
- ): Promise<ReturnType<typeof validateTrustChain>> {
58
- try {
59
- return validateTrustChain(trustAnchorEntity, chain, x509Options);
60
- } catch (error) {
61
- if (renewOnFail) {
62
- const renewedChain = await renewTrustChain(chain, appFetch);
63
- return validateTrustChain(trustAnchorEntity, renewedChain, x509Options);
64
- } else {
65
- throw error;
66
- }
67
- }
68
- }
69
-
70
- /**
71
- * Fetch the signed entity configuration token for an entity
72
- *
73
- * @param entityBaseUrl The url of the entity to fetch
74
- * @param appFetch (optional) fetch api implementation
75
- * @returns The signed Entity Configuration token
76
- */
77
- export async function getSignedEntityConfiguration(
78
- entityBaseUrl: string,
79
- {
80
- appFetch = fetch,
81
- }: {
82
- appFetch?: GlobalFetch["fetch"];
83
- } = {}
84
- ): Promise<string> {
85
- const wellKnownUrl = `${entityBaseUrl}/.well-known/openid-federation`;
86
-
87
- return await appFetch(wellKnownUrl, {
88
- method: "GET",
89
- })
90
- .then(hasStatusOrThrow(200))
91
- .then((res) => res.text());
92
- }
93
-
94
- /**
95
- * Fetch and parse the entity configuration document for a given federation entity.
96
- * This is an inner method to serve public interfaces.
97
- *
98
- * To add another entity configuration type (example: Foo entity type):
99
- * - create its zod schema and type by inherit from the base type (example: FooEntityConfiguration = BaseEntityConfiguration.and(...))
100
- * - add such type to EntityConfiguration union
101
- * - add an overload to this function
102
- * - create a public function which use such type (example: getFooEntityConfiguration = (url, options) => Promise<FooEntityConfiguration>)
103
- *
104
- * @param entityBaseUrl The base url of the entity.
105
- * @param schema The expected schema of the entity configuration, according to the kind of entity we are fetching from.
106
- * @param options An optional object with additional options.
107
- * @param options.appFetch An optional instance of the http client to be used.
108
- * @returns The parsed entity configuration object
109
- * @throws {IoWalletError} If the http request fails
110
- * @throws Parse error if the document is not in the expected shape.
111
- */
112
- async function fetchAndParseEntityConfiguration(
113
- entityBaseUrl: string,
114
- schema: typeof WalletProviderEntityConfiguration,
115
- options?: {
116
- appFetch?: GlobalFetch["fetch"];
117
- }
118
- ): Promise<WalletProviderEntityConfiguration>;
119
- async function fetchAndParseEntityConfiguration(
120
- entityBaseUrl: string,
121
- schema: typeof RelyingPartyEntityConfiguration,
122
- options?: {
123
- appFetch?: GlobalFetch["fetch"];
124
- }
125
- ): Promise<RelyingPartyEntityConfiguration>;
126
- async function fetchAndParseEntityConfiguration(
127
- entityBaseUrl: string,
128
- schema: typeof TrustAnchorEntityConfiguration,
129
- options?: {
130
- appFetch?: GlobalFetch["fetch"];
131
- }
132
- ): Promise<TrustAnchorEntityConfiguration>;
133
- async function fetchAndParseEntityConfiguration(
134
- entityBaseUrl: string,
135
- schema: typeof CredentialIssuerEntityConfiguration,
136
- options?: {
137
- appFetch?: GlobalFetch["fetch"];
138
- }
139
- ): Promise<CredentialIssuerEntityConfiguration>;
140
- async function fetchAndParseEntityConfiguration(
141
- entityBaseUrl: string,
142
- schema: typeof EntityConfiguration,
143
- options?: {
144
- appFetch?: GlobalFetch["fetch"];
145
- }
146
- ): Promise<EntityConfiguration>;
147
- async function fetchAndParseEntityConfiguration(
148
- entityBaseUrl: string,
149
- schema: /* FIXME: why is it different from "typeof EntityConfiguration"? */
150
- | typeof CredentialIssuerEntityConfiguration
151
- | typeof WalletProviderEntityConfiguration
152
- | typeof RelyingPartyEntityConfiguration
153
- | typeof TrustAnchorEntityConfiguration
154
- | typeof EntityConfiguration,
155
- {
156
- appFetch = fetch,
157
- }: {
158
- appFetch?: GlobalFetch["fetch"];
159
- } = {}
160
- ) {
161
- const responseText = await getSignedEntityConfiguration(entityBaseUrl, {
162
- appFetch,
163
- });
164
-
165
- const responseJwt = decodeJwt(responseText);
166
- return schema.parse({
167
- header: responseJwt.protectedHeader,
168
- payload: responseJwt.payload,
169
- });
170
- }
171
-
172
- export const getWalletProviderEntityConfiguration = (
173
- entityBaseUrl: Parameters<typeof fetchAndParseEntityConfiguration>[0],
174
- options?: Parameters<typeof fetchAndParseEntityConfiguration>[2]
175
- ) =>
176
- fetchAndParseEntityConfiguration(
177
- entityBaseUrl,
178
- WalletProviderEntityConfiguration,
179
- options
180
- );
181
-
182
- export const getCredentialIssuerEntityConfiguration = (
183
- entityBaseUrl: Parameters<typeof fetchAndParseEntityConfiguration>[0],
184
- options?: Parameters<typeof fetchAndParseEntityConfiguration>[2]
185
- ) =>
186
- fetchAndParseEntityConfiguration(
187
- entityBaseUrl,
188
- CredentialIssuerEntityConfiguration,
189
- options
190
- );
191
-
192
- export const getTrustAnchorEntityConfiguration = (
193
- entityBaseUrl: Parameters<typeof fetchAndParseEntityConfiguration>[0],
194
- options?: Parameters<typeof fetchAndParseEntityConfiguration>[2]
195
- ) =>
196
- fetchAndParseEntityConfiguration(
197
- entityBaseUrl,
198
- TrustAnchorEntityConfiguration,
199
- options
200
- );
201
-
202
- export const getRelyingPartyEntityConfiguration = (
203
- entityBaseUrl: Parameters<typeof fetchAndParseEntityConfiguration>[0],
204
- options?: Parameters<typeof fetchAndParseEntityConfiguration>[2]
205
- ) =>
206
- fetchAndParseEntityConfiguration(
207
- entityBaseUrl,
208
- RelyingPartyEntityConfiguration,
209
- options
210
- );
211
-
212
- export const getEntityConfiguration = (
213
- entityBaseUrl: Parameters<typeof fetchAndParseEntityConfiguration>[0],
214
- options?: Parameters<typeof fetchAndParseEntityConfiguration>[2]
215
- ) =>
216
- fetchAndParseEntityConfiguration(entityBaseUrl, EntityConfiguration, options);
217
-
218
- /**
219
- * Fetch and parse the entity statement document for a given federation entity.
220
- *
221
- * @param accreditationBodyBaseUrl The base url of the accreditation body which holds and signs the required entity statement
222
- * @param subordinatedEntityBaseUrl The url that identifies the subordinate entity
223
- * @param appFetch An optional instance of the http client to be used.
224
- * @returns The parsed entity configuration object
225
- * @throws {IoWalletError} If the http request fails
226
- */
227
- export async function getEntityStatement(
228
- accreditationBodyBaseUrl: string,
229
- subordinatedEntityBaseUrl: string,
230
- {
231
- appFetch = fetch,
232
- }: {
233
- appFetch?: GlobalFetch["fetch"];
234
- } = {}
235
- ) {
236
- const responseText = await getSignedEntityStatement(
237
- accreditationBodyBaseUrl,
238
- subordinatedEntityBaseUrl,
239
- {
240
- appFetch,
241
- }
242
- );
243
-
244
- const responseJwt = decodeJwt(responseText);
245
- return EntityStatement.parse({
246
- header: responseJwt.protectedHeader,
247
- payload: responseJwt.payload,
248
- });
249
- }
250
-
251
- /**
252
- * Fetch the entity statement document for a given federation entity.
253
- *
254
- * @param federationFetchEndpoint The exact endpoint provided by the parent EC's metadata.
255
- * @param subordinatedEntityBaseUrl The url that identifies the subordinate entity.
256
- * @param appFetch An optional instance of the http client to be used.
257
- * @returns The signed entity statement token.
258
- * @throws {IoWalletError} If the http request fails.
259
- */
260
- export async function getSignedEntityStatement(
261
- federationFetchEndpoint: string,
262
- subordinatedEntityBaseUrl: string,
263
- {
264
- appFetch = fetch,
265
- }: {
266
- appFetch?: GlobalFetch["fetch"];
267
- } = {}
268
- ) {
269
- const url = new URL(federationFetchEndpoint);
270
- url.searchParams.set("sub", subordinatedEntityBaseUrl);
271
-
272
- return await appFetch(url.toString(), {
273
- method: "GET",
274
- })
275
- .then(hasStatusOrThrow(200))
276
- .then((res) => res.text());
277
- }
278
-
279
- /**
280
- * Fetch the federation list document from a given endpoint.
281
- *
282
- * @param federationListEndpoint The URL of the federation list endpoint.
283
- * @param appFetch An optional instance of the http client to be used.
284
- * @returns The federation list as an array of strings.
285
- * @throws {IoWalletError} If the HTTP request fails.
286
- * @throws {FederationError} If the result is not in the expected format.
287
- */
288
- export async function getFederationList(
289
- federationListEndpoint: string,
290
- {
291
- appFetch = fetch,
292
- }: {
293
- appFetch?: GlobalFetch["fetch"];
294
- } = {}
295
- ): Promise<string[]> {
296
- return await appFetch(federationListEndpoint, {
297
- method: "GET",
298
- })
299
- .then(hasStatusOrThrow(200))
300
- .then((res) => res.json())
301
- .then((json) => {
302
- const result = FederationListResponse.safeParse(json);
303
- if (!result.success) {
304
- throw new FederationListParseError(
305
- `Invalid federation list format received from ${federationListEndpoint}. Error: ${result.error.message}`,
306
- { url: federationListEndpoint, parseError: result.error.toString() }
307
- );
308
- }
309
- return result.data;
310
- });
311
- }
312
-
313
- /**
314
- * Build a not-verified trust chain for a given Relying Party (RP) entity.
315
- *
316
- * @param relyingPartyEntityBaseUrl The base URL of the RP entity
317
- * @param trustAnchorKey The public key of the Trust Anchor (TA) entity
318
- * @param appFetch An optional instance of the http client to be used.
319
- * @returns A list of signed tokens that represent the trust chain, in the order of the chain (from the RP to the Trust Anchor)
320
- * @throws {FederationError} When an element of the chain fails to parse or other build steps fail.
321
- */
322
- export async function buildTrustChain(
323
- relyingPartyEntityBaseUrl: string,
324
- trustAnchorKey: JWK,
325
- appFetch: GlobalFetch["fetch"] = fetch
326
- ): Promise<string[]> {
327
- // 1: Recursively gather the trust chain from the RP up to the Trust Anchor
328
- const trustChain = await gatherTrustChain(
329
- relyingPartyEntityBaseUrl,
330
- appFetch
331
- );
332
-
333
- // 2: Trust Anchor signature verification
334
- const trustAnchorJwt = trustChain[trustChain.length - 1];
335
- if (!trustAnchorJwt) {
336
- throw new BuildTrustChainError(
337
- "Cannot verify trust anchor: missing entity configuration in gathered chain.",
338
- { relyingPartyUrl: relyingPartyEntityBaseUrl }
339
- );
340
- }
341
-
342
- if (!trustAnchorKey.kid) {
343
- throw new TrustAnchorKidMissingError();
344
- }
345
-
346
- await verify(trustAnchorJwt, trustAnchorKey.kid, [trustAnchorKey]);
347
-
348
- // 3: Check the federation list
349
- const trustAnchorConfig = EntityConfiguration.parse(decode(trustAnchorJwt));
350
- const federationListEndpoint =
351
- trustAnchorConfig.payload.metadata.federation_entity
352
- .federation_list_endpoint;
353
-
354
- if (federationListEndpoint) {
355
- const federationList = await getFederationList(federationListEndpoint, {
356
- appFetch,
357
- });
358
-
359
- if (!federationList.includes(relyingPartyEntityBaseUrl)) {
360
- throw new RelyingPartyNotAuthorizedError(
361
- "Relying Party entity base URL is not authorized by the Trust Anchor's federation list.",
362
- { relyingPartyUrl: relyingPartyEntityBaseUrl, federationListEndpoint }
363
- );
364
- }
365
- }
366
-
367
- return trustChain;
368
- }
369
-
370
- /**
371
- * Recursively gather the trust chain for an entity and all its superiors.
372
- * @param entityBaseUrl The base URL of the entity for which to gather the chain.
373
- * @param appFetch An optional instance of the http client to be used.
374
- * @param isLeaf Whether the current entity is the leaf of the chain.
375
- * @returns A full ordered list of JWTs (ECs and ESs) forming the trust chain.
376
- * @throws {FederationError} If any of the fetched documents fail to parse or other errors occur during the gathering process.
377
- */
378
- async function gatherTrustChain(
379
- entityBaseUrl: string,
380
- appFetch: GlobalFetch["fetch"],
381
- isLeaf: boolean = true
382
- ): Promise<string[]> {
383
- const chain: string[] = [];
384
-
385
- // Fetch self-signed EC (only needed for the leaf)
386
- const entityECJwt = await getSignedEntityConfiguration(entityBaseUrl, {
387
- appFetch,
388
- });
389
- const entityEC = EntityConfiguration.parse(decode(entityECJwt));
390
-
391
- if (isLeaf) {
392
- // Only push EC for the leaf
393
- chain.push(entityECJwt);
394
- }
395
-
396
- // Find authority_hints (parent, if any)
397
- const authorityHints = entityEC.payload.authority_hints ?? [];
398
- if (authorityHints.length === 0) {
399
- // This is the Trust Anchor (no parent)
400
- if (!isLeaf) {
401
- chain.push(entityECJwt);
402
- }
403
- return chain;
404
- }
405
-
406
- const parentEntityBaseUrl = authorityHints[0]!;
407
-
408
- // Fetch parent EC
409
- const parentECJwt = await getSignedEntityConfiguration(parentEntityBaseUrl, {
410
- appFetch,
411
- });
412
- const parentEC = EntityConfiguration.parse(decode(parentECJwt));
413
-
414
- // Fetch ES
415
- const federationFetchEndpoint =
416
- parentEC.payload.metadata.federation_entity.federation_fetch_endpoint;
417
- if (!federationFetchEndpoint) {
418
- throw new MissingFederationFetchEndpointError(
419
- `Missing federation_fetch_endpoint in parent's (${parentEntityBaseUrl}) configuration when gathering chain for ${entityBaseUrl}.`,
420
- { entityBaseUrl, missingInEntityUrl: parentEntityBaseUrl }
421
- );
422
- }
423
-
424
- const entityStatementJwt = await getSignedEntityStatement(
425
- federationFetchEndpoint,
426
- entityBaseUrl,
427
- { appFetch }
428
- );
429
- // Validate the ES
430
- EntityStatement.parse(decode(entityStatementJwt));
431
-
432
- // Push this ES into the chain
433
- chain.push(entityStatementJwt);
434
-
435
- // Recurse into the parent
436
- const parentChain = await gatherTrustChain(
437
- parentEntityBaseUrl,
438
- appFetch,
439
- false
440
- );
441
-
442
- return chain.concat(parentChain);
443
- }
6
+ export { Build, Verify, Errors, Types };
@@ -37,12 +37,10 @@ const CredentialIssuerDisplayMetadata = z.object({
37
37
  });
38
38
 
39
39
  type ClaimsMetadata = z.infer<typeof ClaimsMetadata>;
40
- const ClaimsMetadata = z.record(
41
- z.object({
42
- value_type: z.string(),
43
- display: z.array(z.object({ name: z.string(), locale: z.string() })),
44
- })
45
- );
40
+ const ClaimsMetadata = z.object({
41
+ path: z.array(z.string()),
42
+ display: z.array(CredentialDisplayMetadata),
43
+ });
46
44
 
47
45
  type IssuanceErrorSupported = z.infer<typeof IssuanceErrorSupported>;
48
46
  const IssuanceErrorSupported = z.object({
@@ -57,16 +55,21 @@ const IssuanceErrorSupported = z.object({
57
55
 
58
56
  // Metadata for a credential which is supported by an Issuer
59
57
  type SupportedCredentialMetadata = z.infer<typeof SupportedCredentialMetadata>;
60
- const SupportedCredentialMetadata = z.object({
61
- format: z.union([z.literal("vc+sd-jwt"), z.literal("vc+mdoc-cbor")]),
62
- scope: z.string(),
63
- display: z.array(CredentialDisplayMetadata),
64
- claims: ClaimsMetadata,
65
- cryptographic_binding_methods_supported: z.array(z.string()),
66
- credential_signing_alg_values_supported: z.array(z.string()),
67
- authentic_source: z.string().optional(),
68
- issuance_errors_supported: z.record(IssuanceErrorSupported).optional(),
69
- });
58
+ const SupportedCredentialMetadata = z.intersection(
59
+ z.discriminatedUnion("format", [
60
+ z.object({ format: z.literal("dc+sd-jwt"), vct: z.string() }),
61
+ z.object({ format: z.literal("mso_mdoc"), doctype: z.string() }),
62
+ ]),
63
+ z.object({
64
+ scope: z.string(),
65
+ display: z.array(CredentialDisplayMetadata),
66
+ claims: z.array(ClaimsMetadata),
67
+ cryptographic_binding_methods_supported: z.array(z.string()),
68
+ credential_signing_alg_values_supported: z.array(z.string()),
69
+ authentic_source: z.string().optional(),
70
+ issuance_errors_supported: z.record(IssuanceErrorSupported).optional(),
71
+ })
72
+ );
70
73
 
71
74
  export type EntityStatement = z.infer<typeof EntityStatement>;
72
75
  export const EntityStatement = z.object({
@@ -155,13 +158,16 @@ export const CredentialIssuerEntityConfiguration = BaseEntityConfiguration.and(
155
158
  openid_credential_issuer: z.object({
156
159
  credential_issuer: z.string(),
157
160
  credential_endpoint: z.string(),
158
- revocation_endpoint: z.string(),
161
+ revocation_endpoint: z.string().optional(),
162
+ nonce_endpoint: z.string(),
159
163
  status_attestation_endpoint: z.string(),
160
164
  display: z.array(CredentialIssuerDisplayMetadata),
161
165
  credential_configurations_supported: z.record(
162
166
  SupportedCredentialMetadata
163
167
  ),
164
168
  jwks: z.object({ keys: z.array(JWK) }),
169
+ trust_frameworks_supported: z.array(z.string()),
170
+ evidence_supported: z.array(z.string()),
165
171
  }),
166
172
  oauth_authorization_server: z.object({
167
173
  authorization_endpoint: z.string(),
@@ -5,7 +5,6 @@ import {
5
5
  } from "./types";
6
6
  import { JWK } from "../utils/jwk";
7
7
  import * as z from "zod";
8
- import { getSignedEntityConfiguration, getSignedEntityStatement } from ".";
9
8
  import {
10
9
  decode,
11
10
  getTrustAnchorX509Certificate,
@@ -26,6 +25,10 @@ import {
26
25
  verifyCertificateChain,
27
26
  type X509CertificateOptions,
28
27
  } from "@pagopa/io-react-native-crypto";
28
+ import {
29
+ getSignedEntityConfiguration,
30
+ getSignedEntityStatement,
31
+ } from "./build-chain";
29
32
 
30
33
  // The first element of the chain is supposed to be the Entity Configuration for the document issuer
31
34
  const FirstElementShape = EntityConfiguration;
@@ -225,3 +228,40 @@ export async function renewTrustChain(
225
228
  })
226
229
  );
227
230
  }
231
+
232
+ /**
233
+ * Verify a given trust chain is actually valid.
234
+ * It can handle fast chain renewal, which means we try to fetch a fresh version of each statement.
235
+ *
236
+ * @param trustAnchorEntity The entity configuration of the known trust anchor
237
+ * @param chain The chain of statements to be validated
238
+ * @param x509Options Options for the verification process
239
+ * @param appFetch (optional) fetch api implementation
240
+ * @param renewOnFail Whether to attempt to renew the trust chain if the initial validation fails
241
+ * @returns The result of the chain validation
242
+ * @throws {FederationError} If the chain is not valid
243
+ */
244
+ export async function verifyTrustChain(
245
+ trustAnchorEntity: TrustAnchorEntityConfiguration,
246
+ chain: string[],
247
+ x509Options: X509CertificateOptions = {
248
+ connectTimeout: 10000,
249
+ readTimeout: 10000,
250
+ requireCrl: true,
251
+ },
252
+ {
253
+ appFetch = fetch,
254
+ renewOnFail = true,
255
+ }: { appFetch?: GlobalFetch["fetch"]; renewOnFail?: boolean } = {}
256
+ ): Promise<ReturnType<typeof validateTrustChain>> {
257
+ try {
258
+ return validateTrustChain(trustAnchorEntity, chain, x509Options);
259
+ } catch (error) {
260
+ if (renewOnFail) {
261
+ const renewedChain = await renewTrustChain(chain, appFetch);
262
+ return validateTrustChain(trustAnchorEntity, renewedChain, x509Options);
263
+ } else {
264
+ throw error;
265
+ }
266
+ }
267
+ }
@@ -1,13 +1,13 @@
1
1
  import type { ProblemDetail } from "../client/generated/wallet-provider";
2
- import type { CredentialIssuerEntityConfiguration } from "../trust";
3
2
  import {
3
+ type IssuerResponseErrorCode,
4
4
  IssuerResponseErrorCodes,
5
- WalletProviderResponseErrorCodes,
5
+ type RelyingPartyResponseErrorCode,
6
6
  RelyingPartyResponseErrorCodes,
7
- type IssuerResponseErrorCode,
8
7
  type WalletProviderResponseErrorCode,
9
- type RelyingPartyResponseErrorCode,
8
+ WalletProviderResponseErrorCodes,
10
9
  } from "./error-codes";
10
+ import type { CredentialIssuerEntityConfiguration } from "../trust/types";
11
11
 
12
12
  export {
13
13
  IssuerResponseErrorCodes,