@pagopa/io-react-native-wallet 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/lib/commonjs/credential/presentation/01-start-flow.js +12 -28
  2. package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
  3. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +96 -24
  4. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -1
  5. package/lib/commonjs/credential/presentation/05-verify-request-object.js +7 -2
  6. package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -1
  7. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +9 -5
  8. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  9. package/lib/commonjs/credential/presentation/README.md +4 -4
  10. package/lib/commonjs/credential/presentation/errors.js +2 -19
  11. package/lib/commonjs/credential/presentation/errors.js.map +1 -1
  12. package/lib/commonjs/credential/presentation/types.js +7 -1
  13. package/lib/commonjs/credential/presentation/types.js.map +1 -1
  14. package/lib/commonjs/utils/crypto.js +41 -1
  15. package/lib/commonjs/utils/crypto.js.map +1 -1
  16. package/lib/module/credential/presentation/01-start-flow.js +12 -28
  17. package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
  18. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +96 -24
  19. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -1
  20. package/lib/module/credential/presentation/05-verify-request-object.js +7 -2
  21. package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -1
  22. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +9 -5
  23. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  24. package/lib/module/credential/presentation/README.md +4 -4
  25. package/lib/module/credential/presentation/errors.js +0 -16
  26. package/lib/module/credential/presentation/errors.js.map +1 -1
  27. package/lib/module/credential/presentation/types.js +7 -1
  28. package/lib/module/credential/presentation/types.js.map +1 -1
  29. package/lib/module/utils/crypto.js +38 -0
  30. package/lib/module/utils/crypto.js.map +1 -1
  31. package/lib/typescript/credential/presentation/01-start-flow.d.ts +3 -3
  32. package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
  33. package/lib/typescript/credential/presentation/03-get-request-object.d.ts +1 -1
  34. package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts +15 -8
  35. package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts.map +1 -1
  36. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -1
  37. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +3 -2
  38. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
  39. package/lib/typescript/credential/presentation/errors.d.ts +0 -11
  40. package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
  41. package/lib/typescript/credential/presentation/types.d.ts +242 -3
  42. package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
  43. package/lib/typescript/utils/crypto.d.ts +24 -0
  44. package/lib/typescript/utils/crypto.d.ts.map +1 -1
  45. package/package.json +3 -1
  46. package/src/credential/presentation/01-start-flow.ts +16 -32
  47. package/src/credential/presentation/03-get-request-object.ts +1 -1
  48. package/src/credential/presentation/04-retrieve-rp-jwks.ts +122 -34
  49. package/src/credential/presentation/05-verify-request-object.ts +4 -3
  50. package/src/credential/presentation/07-evaluate-input-descriptor.ts +20 -6
  51. package/src/credential/presentation/README.md +4 -4
  52. package/src/credential/presentation/errors.ts +0 -16
  53. package/src/credential/presentation/types.ts +8 -1
  54. package/src/utils/crypto.ts +43 -0
@@ -15,9 +15,10 @@ export const verifyRequestObjectSignature: VerifyRequestObjectSignature =
15
15
  const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
16
16
 
17
17
  // verify token signature to ensure the request object is authentic
18
- const pubKey = jwkKeys?.find(
19
- ({ kid }) => kid === requestObjectJwt.protectedHeader.kid
20
- );
18
+ const pubKey =
19
+ jwkKeys?.find(
20
+ ({ kid }) => kid === requestObjectJwt.protectedHeader.kid
21
+ ) || jwkKeys?.find(({ use }) => use === "sig");
21
22
 
22
23
  if (!pubKey) {
23
24
  throw new UnverifiedEntityError("Request Object signature verification!");
@@ -9,6 +9,7 @@ const INDEX_CLAIM_NAME = 1;
9
9
  export type EvaluatedDisclosures = {
10
10
  requiredDisclosures: DisclosureWithEncoded[];
11
11
  optionalDisclosures: DisclosureWithEncoded[];
12
+ unrequestedDisclosures: DisclosureWithEncoded[];
12
13
  };
13
14
 
14
15
  export type EvaluateInputDescriptorSdJwt4VC = (
@@ -99,8 +100,8 @@ const extractClaimName = (path: string): string | undefined => {
99
100
  * - Validates whether required fields are present (unless marked optional)
100
101
  * and match any specified JSONPath.
101
102
  * - If a field includes a JSON Schema filter, validates the claim value against that schema.
102
- * - Enforces `limit_disclosure` rules by returning only disclosures matching the specified fields
103
- * if set to "required". Otherwise return the array of all disclosures.
103
+ * - Enforces `limit_disclosure` rules by returning only disclosures, required and optional, matching the specified fields
104
+ * if set to "required". Otherwise also return the array unrequestedDisclosures with disclosures which can be passed for a particular use case.
104
105
  * - Throws an error if a required field is invalid or missing.
105
106
  *
106
107
  * @param inputDescriptor - Describes constraints (fields, filters, etc.) that must be satisfied.
@@ -115,7 +116,8 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
115
116
  // No validation, all field are optional
116
117
  return {
117
118
  requiredDisclosures: [],
118
- optionalDisclosures: disclosures,
119
+ optionalDisclosures: [],
120
+ unrequestedDisclosures: disclosures,
119
121
  };
120
122
  }
121
123
  const requiredClaimNames: string[] = [];
@@ -182,9 +184,6 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
182
184
  }
183
185
 
184
186
  // Categorizes disclosures into required and optional based on claim names and disclosure constraints.
185
- const isNotLimitDisclosure = !(
186
- inputDescriptor.constraints.limit_disclosure === "required"
187
- );
188
187
 
189
188
  const requiredDisclosures = disclosures.filter((disclosure) =>
190
189
  requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
@@ -197,8 +196,23 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
197
196
  !requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]))
198
197
  );
199
198
 
199
+ const isNotLimitDisclosure = !(
200
+ inputDescriptor.constraints.limit_disclosure === "required"
201
+ );
202
+
203
+ const unrequestedDisclosures = isNotLimitDisclosure
204
+ ? disclosures.filter(
205
+ (disclosure) =>
206
+ !optionalClaimNames.includes(
207
+ disclosure.decoded[INDEX_CLAIM_NAME]
208
+ ) &&
209
+ !requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
210
+ )
211
+ : [];
212
+
200
213
  return {
201
214
  requiredDisclosures,
202
215
  optionalDisclosures,
216
+ unrequestedDisclosures,
203
217
  };
204
218
  };
@@ -29,8 +29,8 @@ sequenceDiagram
29
29
  <summary>Remote Presentation flow</summary>
30
30
 
31
31
  ```ts
32
- // Scan e retrive qr-code
33
- const qrcode = ...
32
+ // Scan e retrive qr-code, decode it and get its parameters
33
+ const {requestUri, clientId} = ...
34
34
 
35
35
  // Retrieve the integrity key tag from the store and create its context
36
36
  const integrityKeyTag = "example"; // Let's assume this is the key tag used to create the wallet instance
@@ -55,7 +55,7 @@ const walletInstanceAttestation =
55
55
  });
56
56
 
57
57
  // Start the issuance flow
58
- const { requestURI, clientId } = Credential.Presentation.startFlowFromQR(qrcode);
58
+ const { requestURI, clientId } = Credential.Presentation.startFlowFromQR(requestUri, clientId);
59
59
 
60
60
  // If use trust federation: Evaluate issuer trust
61
61
  const { rpConf } = await Credential.Presentation.evaluateRelyingPartyTrust(clientId);
@@ -111,4 +111,4 @@ const { presentationDefinition } = await Credential.Presentation.fetchPresentDef
111
111
 
112
112
  ```
113
113
 
114
- </details>
114
+ </details>
@@ -40,22 +40,6 @@ export class NoSuitableKeysFoundInEntityConfiguration extends IoWalletError {
40
40
  }
41
41
  }
42
42
 
43
- /**
44
- * When a QR code is not valid.
45
- *
46
- */
47
- export class InvalidQRCodeError extends IoWalletError {
48
- code = "ERR_INVALID_QR_CODE";
49
-
50
- /**
51
- * @param detail A description of why the QR code is considered invalid.
52
- */
53
- constructor(detail: string) {
54
- const message = `QR code is not valid: ${detail}.`;
55
- super(message);
56
- }
57
- }
58
-
59
43
  /**
60
44
  * When the entity is unverified because the Relying Party is not trusted.
61
45
  *
@@ -1,6 +1,7 @@
1
1
  import type { CryptoContext } from "@pagopa/io-react-native-jwt";
2
2
  import { UnixTime } from "../../sd-jwt/types";
3
3
  import * as z from "zod";
4
+ import { JWKS } from "../../utils/jwk";
4
5
 
5
6
  /**
6
7
  * A pair that associate a tokenized Verified Credential with the claims presented or requested to present.
@@ -77,7 +78,13 @@ export const RequestObject = z.object({
77
78
  response_type: z.literal("vp_token"),
78
79
  response_mode: z.enum(["direct_post.jwt", "direct_post"]),
79
80
  client_id: z.string(),
80
- client_id_scheme: z.string(), // previous z.literal("entity_id"),
81
+ client_id_scheme: z.string().optional(), // previous z.literal("entity_id"),
82
+ client_metadata: z
83
+ .object({
84
+ jwks_uri: z.string().optional(),
85
+ jwks: JWKS.optional(),
86
+ })
87
+ .optional(), // previous z.literal("entity_id"),
81
88
  scope: z.string().optional(),
82
89
  presentation_definition: PresentationDefinition.optional(),
83
90
  });
@@ -7,6 +7,8 @@ import {
7
7
  import uuid from "react-native-uuid";
8
8
  import { thumbprint, type CryptoContext } from "@pagopa/io-react-native-jwt";
9
9
  import { fixBase64EncodingOnKey } from "./jwk";
10
+ import { X509, KEYUTIL, RSAKey, KJUR } from "jsrsasign";
11
+ import { JWK } from "./jwk";
10
12
 
11
13
  /**
12
14
  * Create a CryptoContext bound to a key pair.
@@ -63,3 +65,44 @@ export const withEphemeralKey = async <R>(
63
65
  const ephemeralContext = createCryptoContextFor(keytag);
64
66
  return fn(ephemeralContext).finally(() => deleteKey(keytag));
65
67
  };
68
+
69
+ /**
70
+ * Converts a certificate string to PEM format.
71
+ *
72
+ * @param certificate - The certificate string.
73
+ * @returns The PEM-formatted certificate.
74
+ */
75
+ export const convertCertToPem = (certificate: string): string =>
76
+ `-----BEGIN CERTIFICATE-----\n${certificate}\n-----END CERTIFICATE-----`;
77
+
78
+ /**
79
+ * Parses the public key from a PEM-formatted certificate.
80
+ *
81
+ * @param pemCert - The PEM-formatted certificate.
82
+ * @returns The public key object.
83
+ * @throws Will throw an error if the public key is unsupported.
84
+ */
85
+ export const parsePublicKey = (
86
+ pemCert: string
87
+ ): RSAKey | KJUR.crypto.ECDSA | undefined => {
88
+ const x509 = new X509();
89
+ x509.readCertPEM(pemCert);
90
+ const publicKey = x509.getPublicKey();
91
+
92
+ if (publicKey instanceof RSAKey || publicKey instanceof KJUR.crypto.ECDSA) {
93
+ return publicKey;
94
+ }
95
+
96
+ return undefined;
97
+ };
98
+
99
+ /**
100
+ * Retrieves the signing JWK from the public key.
101
+ *
102
+ * @param publicKey - The public key object.
103
+ * @returns The signing JWK.
104
+ */
105
+ export const getSigningJwk = (publicKey: RSAKey | KJUR.crypto.ECDSA): JWK => ({
106
+ ...JWK.parse(KEYUTIL.getJWKFromKey(publicKey)),
107
+ use: "sig",
108
+ });