@gramota/oid4vp 0.2.1 → 0.3.0

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.
package/dist/cert.d.ts CHANGED
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import "reflect-metadata";
20
20
  import type { JsonWebKey } from "@gramota/jose";
21
- import { type SigningCert } from "./types.js";
21
+ import { type ClientIdScheme, type SigningCert } from "./types.js";
22
22
  export interface GenerateSigningCertOptions {
23
23
  /** Primary DNS name for the cert's Subject Alternative Name. Must match
24
24
  * the verifier's hostname (the part the wallet sees in the OID4VP
@@ -69,4 +69,60 @@ export declare function signingCertToJwks(cert: SigningCert): Promise<{
69
69
  publicJwk: JsonWebKey;
70
70
  privateJwk: JsonWebKey;
71
71
  }>;
72
+ /**
73
+ * Compute the `x509_hash` digest of a signing cert per OID4VP §5.9.3 +
74
+ * HAIP Final 1.0 §5: `base64url(SHA-256(DER-encoded leaf certificate))`.
75
+ *
76
+ * The leaf cert's DER bytes are taken from the first entry of {@link
77
+ * SigningCert.x5c}. That entry is already base64-encoded DER (no PEM
78
+ * armour) — we decode, hash, and base64url-encode the digest.
79
+ *
80
+ * The result becomes the value part of the `x509_hash:<digest>` Client
81
+ * Identifier. Wallets that see this prefix:
82
+ * 1. Read the JWS `x5c` header.
83
+ * 2. Compute the same hash over the leaf cert.
84
+ * 3. Compare against the value portion of `client_id`.
85
+ * 4. If they match, the cert is the verifier's authentic key.
86
+ *
87
+ * Unlike `x509_san_dns`, the cert's SAN is not consulted — the cert
88
+ * itself, via its hash, IS the identity. This makes the prefix the
89
+ * spec-preferred form for HAIP Final 1.0: an attacker who steals the
90
+ * `client_id` cannot substitute a different (same-SAN) cert.
91
+ *
92
+ * @throws {@link Oid4vpError} `oid4vp.cert_generation_failed` when the
93
+ * cert's `x5c` is missing or the leaf bytes are malformed base64.
94
+ */
95
+ export declare function computeCertX509Hash(cert: SigningCert): string;
96
+ /** Schemes {@link buildClientIdFromCert} can construct. */
97
+ export type CertBackedClientIdScheme = "x509_san_dns" | "x509_hash";
98
+ export interface BuildClientIdFromCertOptions {
99
+ /** Signing material the verifier already provisioned. */
100
+ readonly cert: SigningCert;
101
+ /** Prefix to emit. Default `"x509_hash"` — HAIP Final 1.0 §5 mandates
102
+ * this prefix for production HAIP-conformant verifiers. Use
103
+ * `"x509_san_dns"` only for legacy / emulator interop where the wallet
104
+ * doesn't yet accept `x509_hash`. */
105
+ readonly scheme?: CertBackedClientIdScheme;
106
+ }
107
+ /**
108
+ * Build the OID4VP `client_id` for a cert-backed verifier.
109
+ *
110
+ * Returns the prefixed identifier per OID4VP §5.9.3:
111
+ *
112
+ * - `x509_san_dns:<sanDns>` — legacy. Wallet looks up the cert's SAN
113
+ * DNS entry; useful when wallets pre-resolve identity by hostname.
114
+ * - `x509_hash:<base64url(sha256(DER(leaf)))>` — HAIP Final 1.0 §5
115
+ * bullet 3 (MUST for HAIP-conformant verifiers). Wallet hashes the
116
+ * leaf cert in the JWS `x5c` header and compares — no DNS coupling.
117
+ *
118
+ * Pair the returned `client_id` with the matching {@link ClientIdScheme}
119
+ * literal when populating an {@link AuthorizationRequest}.
120
+ *
121
+ * @throws {@link Oid4vpError} `oid4vp.cert_generation_failed` for an
122
+ * unknown scheme, missing SAN-DNS, or malformed `x5c`.
123
+ */
124
+ export declare function buildClientIdFromCert(options: BuildClientIdFromCertOptions): {
125
+ clientId: string;
126
+ scheme: ClientIdScheme;
127
+ };
72
128
  //# sourceMappingURL=cert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cert.d.ts","sourceRoot":"","sources":["../src/cert.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAc3D,MAAM,WAAW,0BAA0B;IACzC;;wDAEoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;iDAE6C;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;sBACkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,WAAW,CAAC,CAyFtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,SAAS,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC,CAmC5D"}
1
+ {"version":3,"file":"cert.d.ts","sourceRoot":"","sources":["../src/cert.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAcpB,MAAM,WAAW,0BAA0B;IACzC;;wDAEoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;iDAE6C;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;sBACkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,WAAW,CAAC,CAyFtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,SAAS,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC,CAmC5D;AA2CD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAgC7D;AAED,2DAA2D;AAC3D,MAAM,MAAM,wBAAwB,GAAG,cAAc,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,4BAA4B;IAC3C,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B;;;yCAGqC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,4BAA4B,GACpC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAyB9C"}
package/dist/cert.js CHANGED
@@ -22,9 +22,9 @@
22
22
  // `dist/cert.js` as a side-effecting module so bundlers don't drop it.
23
23
  import "reflect-metadata";
24
24
  import * as x509 from "@peculiar/x509";
25
- import { webcrypto } from "node:crypto";
25
+ import { createHash, webcrypto } from "node:crypto";
26
26
  import { exportJWK, importPKCS8, importX509 } from "jose";
27
- import { Oid4vpError } from "./types.js";
27
+ import { Oid4vpError, } from "./types.js";
28
28
  // @peculiar/x509 needs a Web Crypto provider — Node's webcrypto suffices.
29
29
  // Safe to call multiple times; no-op after first.
30
30
  let cryptoProviderSet = false;
@@ -188,4 +188,86 @@ function derToPem(der, label) {
188
188
  function bytesToBase64(bytes) {
189
189
  return Buffer.from(bytes).toString("base64");
190
190
  }
191
+ // ---------------------------------------------------------------------------
192
+ // Client Identifier Prefixes — OID4VP §5.9.3, HAIP Final 1.0 §5.
193
+ // ---------------------------------------------------------------------------
194
+ /**
195
+ * Compute the `x509_hash` digest of a signing cert per OID4VP §5.9.3 +
196
+ * HAIP Final 1.0 §5: `base64url(SHA-256(DER-encoded leaf certificate))`.
197
+ *
198
+ * The leaf cert's DER bytes are taken from the first entry of {@link
199
+ * SigningCert.x5c}. That entry is already base64-encoded DER (no PEM
200
+ * armour) — we decode, hash, and base64url-encode the digest.
201
+ *
202
+ * The result becomes the value part of the `x509_hash:<digest>` Client
203
+ * Identifier. Wallets that see this prefix:
204
+ * 1. Read the JWS `x5c` header.
205
+ * 2. Compute the same hash over the leaf cert.
206
+ * 3. Compare against the value portion of `client_id`.
207
+ * 4. If they match, the cert is the verifier's authentic key.
208
+ *
209
+ * Unlike `x509_san_dns`, the cert's SAN is not consulted — the cert
210
+ * itself, via its hash, IS the identity. This makes the prefix the
211
+ * spec-preferred form for HAIP Final 1.0: an attacker who steals the
212
+ * `client_id` cannot substitute a different (same-SAN) cert.
213
+ *
214
+ * @throws {@link Oid4vpError} `oid4vp.cert_generation_failed` when the
215
+ * cert's `x5c` is missing or the leaf bytes are malformed base64.
216
+ */
217
+ export function computeCertX509Hash(cert) {
218
+ if (cert === null ||
219
+ typeof cert !== "object" ||
220
+ !Array.isArray(cert.x5c) ||
221
+ cert.x5c.length === 0 ||
222
+ typeof cert.x5c[0] !== "string" ||
223
+ cert.x5c[0].length === 0) {
224
+ throw new Oid4vpError("oid4vp.cert_generation_failed", "computeCertX509Hash: cert.x5c[0] must be a non-empty base64-DER string");
225
+ }
226
+ let der;
227
+ try {
228
+ der = Buffer.from(cert.x5c[0], "base64");
229
+ }
230
+ catch (err) {
231
+ throw new Oid4vpError("oid4vp.cert_generation_failed", `computeCertX509Hash: failed to decode cert.x5c[0]: ${err instanceof Error ? err.message : String(err)}`);
232
+ }
233
+ if (der.length === 0) {
234
+ throw new Oid4vpError("oid4vp.cert_generation_failed", "computeCertX509Hash: cert.x5c[0] decoded to zero bytes");
235
+ }
236
+ return createHash("sha256").update(der).digest("base64url");
237
+ }
238
+ /**
239
+ * Build the OID4VP `client_id` for a cert-backed verifier.
240
+ *
241
+ * Returns the prefixed identifier per OID4VP §5.9.3:
242
+ *
243
+ * - `x509_san_dns:<sanDns>` — legacy. Wallet looks up the cert's SAN
244
+ * DNS entry; useful when wallets pre-resolve identity by hostname.
245
+ * - `x509_hash:<base64url(sha256(DER(leaf)))>` — HAIP Final 1.0 §5
246
+ * bullet 3 (MUST for HAIP-conformant verifiers). Wallet hashes the
247
+ * leaf cert in the JWS `x5c` header and compares — no DNS coupling.
248
+ *
249
+ * Pair the returned `client_id` with the matching {@link ClientIdScheme}
250
+ * literal when populating an {@link AuthorizationRequest}.
251
+ *
252
+ * @throws {@link Oid4vpError} `oid4vp.cert_generation_failed` for an
253
+ * unknown scheme, missing SAN-DNS, or malformed `x5c`.
254
+ */
255
+ export function buildClientIdFromCert(options) {
256
+ const scheme = options.scheme ?? "x509_hash";
257
+ if (scheme === "x509_san_dns") {
258
+ if (typeof options.cert?.sanDns !== "string" ||
259
+ options.cert.sanDns.length === 0) {
260
+ throw new Oid4vpError("oid4vp.cert_generation_failed", "buildClientIdFromCert(x509_san_dns): cert.sanDns is required");
261
+ }
262
+ return {
263
+ clientId: `x509_san_dns:${options.cert.sanDns}`,
264
+ scheme: "x509_san_dns",
265
+ };
266
+ }
267
+ if (scheme === "x509_hash") {
268
+ const digest = computeCertX509Hash(options.cert);
269
+ return { clientId: `x509_hash:${digest}`, scheme: "x509_hash" };
270
+ }
271
+ throw new Oid4vpError("oid4vp.cert_generation_failed", `buildClientIdFromCert: unknown scheme ${JSON.stringify(scheme)}`);
272
+ }
191
273
  //# sourceMappingURL=cert.js.map
package/dist/cert.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cert.js","sourceRoot":"","sources":["../src/cert.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cert.js","sourceRoot":"","sources":["../src/cert.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { buildAuthorizationRequestUrl, parseAuthorizationRequestUrl, parseAuthorizationRequestSearchParams, } from "./request.js";
2
2
  export { buildAuthorizationResponseBody, parseAuthorizationResponseBody, parseAuthorizationResponseFromParams, } from "./response.js";
3
- export { generateSigningCert, signingCertToJwks, type GenerateSigningCertOptions, } from "./cert.js";
4
- export { signAuthorizationRequest, type SignAuthorizationRequestOptions, } from "./jar.js";
3
+ export { buildClientIdFromCert, computeCertX509Hash, generateSigningCert, signingCertToJwks, type BuildClientIdFromCertOptions, type CertBackedClientIdScheme, type GenerateSigningCertOptions, } from "./cert.js";
4
+ export { DEFAULT_JAR_AUDIENCE, DEFAULT_JAR_LIFETIME_SECONDS, signAuthorizationRequest, type SignAuthorizationRequestOptions, } from "./jar.js";
5
+ export { generateNonce, generateState, } from "./random.js";
6
+ export { DEFAULT_RESPONSE_JWE_ALG, DEFAULT_RESPONSE_JWE_ENC, decryptAuthorizationResponse, encryptAuthorizationResponse, generateResponseEncryptionKey, type DecryptAuthorizationResponseOptions, type DecryptedAuthorizationResponse, type EncryptAuthorizationResponseOptions, type GenerateResponseEncryptionKeyOptions, } from "./response-jwt.js";
5
7
  export { Oid4vpError, type AuthorizationRequest, type AuthorizationResponse, type ClientIdScheme, type Oid4vpErrorCode, type ResponseMode, type SigningCert, } from "./types.js";
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,qCAAqC,GACtC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,0BAA0B,GAChC,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,qCAAqC,GACtC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,GAChC,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,EAC5B,6BAA6B,EAC7B,KAAK,mCAAmC,EACxC,KAAK,8BAA8B,EACnC,KAAK,mCAAmC,EACxC,KAAK,oCAAoC,GAC1C,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  export { buildAuthorizationRequestUrl, parseAuthorizationRequestUrl, parseAuthorizationRequestSearchParams, } from "./request.js";
2
2
  export { buildAuthorizationResponseBody, parseAuthorizationResponseBody, parseAuthorizationResponseFromParams, } from "./response.js";
3
- export { generateSigningCert, signingCertToJwks, } from "./cert.js";
4
- export { signAuthorizationRequest, } from "./jar.js";
3
+ export { buildClientIdFromCert, computeCertX509Hash, generateSigningCert, signingCertToJwks, } from "./cert.js";
4
+ export { DEFAULT_JAR_AUDIENCE, DEFAULT_JAR_LIFETIME_SECONDS, signAuthorizationRequest, } from "./jar.js";
5
+ export { generateNonce, generateState, } from "./random.js";
6
+ export { DEFAULT_RESPONSE_JWE_ALG, DEFAULT_RESPONSE_JWE_ENC, decryptAuthorizationResponse, encryptAuthorizationResponse, generateResponseEncryptionKey, } from "./response-jwt.js";
5
7
  export { Oid4vpError, } from "./types.js";
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,qCAAqC,GACtC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAElB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,wBAAwB,GAEzB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,WAAW,GAOZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,qCAAqC,GACtC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,GAIlB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,wBAAwB,GAEzB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,EAC5B,6BAA6B,GAK9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,GAOZ,MAAM,YAAY,CAAC"}
package/dist/jar.d.ts CHANGED
@@ -17,8 +17,27 @@
17
17
  * For the EUDIW HAIP profile + the EU reference wallet's demo build,
18
18
  * `x509_san_dns` (with this signed JAR shape) is the only `client_id_prefix`
19
19
  * the wallet accepts. Production verifiers MUST sign their requests.
20
+ *
21
+ * In addition to the OID4VP request claims, the signer always emits the
22
+ * standard JWT claims `aud`, `iat`, `exp` on the JAR payload (RFC 9101
23
+ * §4 recommends them; OID4VP §5.8 mandates `aud`; HAIP-strict wallets
24
+ * reject when any of the three is absent). The audience defaults to the
25
+ * static pseudo-issuer `https://self-issued.me/v2` and the lifetime
26
+ * defaults to 5 minutes — both are configurable per call.
20
27
  */
21
28
  import { type AuthorizationRequest, type SigningCert } from "./types.js";
29
+ /** OID4VP §5.8 — default `aud` for the signed JAR. Wallets check `aud`
30
+ * against either their own issuer URL (dynamic discovery) or the static
31
+ * pseudo-issuer `https://self-issued.me/v2`. We don't do dynamic wallet
32
+ * discovery — so the static value is the right default per the HAIP
33
+ * convention. Callers can override via `SignAuthorizationRequestOptions.aud`
34
+ * when targeting wallets that announce themselves via `wallet_metadata`. */
35
+ export declare const DEFAULT_JAR_AUDIENCE = "https://self-issued.me/v2";
36
+ /** Default JAR lifetime — 5 minutes. RFC 9101 §4 doesn't fix a value but
37
+ * recommends a "short" lifetime; HAIP doesn't pin one either. 5 min
38
+ * matches OID4VCI's c_nonce window for symmetry across endpoints, and is
39
+ * the audit-recommended default (EUDI compliance audit, 2026-05). */
40
+ export declare const DEFAULT_JAR_LIFETIME_SECONDS: number;
22
41
  export interface SignAuthorizationRequestOptions {
23
42
  /** The verifier's Authorization Request to sign. Must already include
24
43
  * the verifier-side fields (`client_id`, `nonce`, `response_uri`, etc).
@@ -27,6 +46,20 @@ export interface SignAuthorizationRequestOptions {
27
46
  /** The verifier's signing material — produced by `generateSigningCert`
28
47
  * or supplied externally. */
29
48
  readonly cert: SigningCert;
49
+ /** Audience for the signed JAR. Defaults to {@link DEFAULT_JAR_AUDIENCE}
50
+ * (`https://self-issued.me/v2`) per HAIP convention (RFC 9101 §2.1 +
51
+ * OID4VP §5.8). Pass `undefined` explicitly to fall through to the
52
+ * default — a JAR is never emitted without an `aud` claim. */
53
+ readonly aud?: string;
54
+ /** JAR lifetime in seconds. `iat = now`, `exp = now + lifetime`.
55
+ * Defaults to {@link DEFAULT_JAR_LIFETIME_SECONDS} (300 = 5 min).
56
+ * (OID4VP §5.8 + RFC 9101 §4) */
57
+ readonly jarLifetimeSeconds?: number;
58
+ /** Override `iat` source — useful for deterministic tests. Defaults
59
+ * to `() => Math.floor(Date.now() / 1000)`. Returned value is treated
60
+ * as the unix-seconds timestamp written to `iat`; `exp` is
61
+ * `now() + jarLifetimeSeconds`. */
62
+ readonly now?: () => number;
30
63
  }
31
64
  /**
32
65
  * Sign an OID4VP Authorization Request as a compact-serialised JWS,
@@ -40,8 +73,15 @@ export interface SignAuthorizationRequestOptions {
40
73
  * separate key-discovery step
41
74
  *
42
75
  * The JWS payload IS the request object — claims at the top level, not
43
- * wrapped in some envelope (RFC 9101 §10.2). Caller serves the result
44
- * with content type `application/oauth-authz-req+jwt`.
76
+ * wrapped in some envelope (RFC 9101 §10.2). On top of the request
77
+ * claims the signer always overlays:
78
+ * - `aud` — defaults to `https://self-issued.me/v2`
79
+ * - `iat` — set to `now()` (unix seconds)
80
+ * - `exp` — set to `iat + jarLifetimeSeconds` (default 300 s)
81
+ *
82
+ * If the request payload already carries any of `aud`/`iat`/`exp`, those
83
+ * payload-level values win — the signer is non-destructive. Caller
84
+ * serves the result with content type `application/oauth-authz-req+jwt`.
45
85
  *
46
86
  * @throws {@link Oid4vpError} with `oid4vp.jar_signing_failed` if the
47
87
  * private key is malformed or signing fails.
package/dist/jar.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jar.d.ts","sourceRoot":"","sources":["../src/jar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,+BAA+B;IAC9C;;2EAEuE;IACvE,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC;iCAC6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,MAAM,CAAC,CAqDjB"}
1
+ {"version":3,"file":"jar.d.ts","sourceRoot":"","sources":["../src/jar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAEpB;;;;;4EAK4E;AAC5E,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAEhE;;;qEAGqE;AACrE,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,MAAM,WAAW,+BAA+B;IAC9C;;2EAEuE;IACvE,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC;iCAC6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B;;;kEAG8D;IAC9D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;qCAEiC;IACjC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;uCAGmC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,MAAM,CAAC,CAwEjB"}
package/dist/jar.js CHANGED
@@ -17,9 +17,28 @@
17
17
  * For the EUDIW HAIP profile + the EU reference wallet's demo build,
18
18
  * `x509_san_dns` (with this signed JAR shape) is the only `client_id_prefix`
19
19
  * the wallet accepts. Production verifiers MUST sign their requests.
20
+ *
21
+ * In addition to the OID4VP request claims, the signer always emits the
22
+ * standard JWT claims `aud`, `iat`, `exp` on the JAR payload (RFC 9101
23
+ * §4 recommends them; OID4VP §5.8 mandates `aud`; HAIP-strict wallets
24
+ * reject when any of the three is absent). The audience defaults to the
25
+ * static pseudo-issuer `https://self-issued.me/v2` and the lifetime
26
+ * defaults to 5 minutes — both are configurable per call.
20
27
  */
21
28
  import { SignJWT, importPKCS8 } from "jose";
22
29
  import { Oid4vpError, } from "./types.js";
30
+ /** OID4VP §5.8 — default `aud` for the signed JAR. Wallets check `aud`
31
+ * against either their own issuer URL (dynamic discovery) or the static
32
+ * pseudo-issuer `https://self-issued.me/v2`. We don't do dynamic wallet
33
+ * discovery — so the static value is the right default per the HAIP
34
+ * convention. Callers can override via `SignAuthorizationRequestOptions.aud`
35
+ * when targeting wallets that announce themselves via `wallet_metadata`. */
36
+ export const DEFAULT_JAR_AUDIENCE = "https://self-issued.me/v2";
37
+ /** Default JAR lifetime — 5 minutes. RFC 9101 §4 doesn't fix a value but
38
+ * recommends a "short" lifetime; HAIP doesn't pin one either. 5 min
39
+ * matches OID4VCI's c_nonce window for symmetry across endpoints, and is
40
+ * the audit-recommended default (EUDI compliance audit, 2026-05). */
41
+ export const DEFAULT_JAR_LIFETIME_SECONDS = 5 * 60;
23
42
  /**
24
43
  * Sign an OID4VP Authorization Request as a compact-serialised JWS,
25
44
  * formatted per RFC 9101 + OID4VP §5.10.
@@ -32,8 +51,15 @@ import { Oid4vpError, } from "./types.js";
32
51
  * separate key-discovery step
33
52
  *
34
53
  * The JWS payload IS the request object — claims at the top level, not
35
- * wrapped in some envelope (RFC 9101 §10.2). Caller serves the result
36
- * with content type `application/oauth-authz-req+jwt`.
54
+ * wrapped in some envelope (RFC 9101 §10.2). On top of the request
55
+ * claims the signer always overlays:
56
+ * - `aud` — defaults to `https://self-issued.me/v2`
57
+ * - `iat` — set to `now()` (unix seconds)
58
+ * - `exp` — set to `iat + jarLifetimeSeconds` (default 300 s)
59
+ *
60
+ * If the request payload already carries any of `aud`/`iat`/`exp`, those
61
+ * payload-level values win — the signer is non-destructive. Caller
62
+ * serves the result with content type `application/oauth-authz-req+jwt`.
37
63
  *
38
64
  * @throws {@link Oid4vpError} with `oid4vp.jar_signing_failed` if the
39
65
  * private key is malformed or signing fails.
@@ -54,13 +80,32 @@ export async function signAuthorizationRequest(options) {
54
80
  catch (err) {
55
81
  throw new Oid4vpError("oid4vp.jar_signing_failed", `signAuthorizationRequest: failed to import private key: ${err instanceof Error ? err.message : String(err)}`);
56
82
  }
83
+ // Resolve the JWT timing claims. `options.aud === undefined` falls
84
+ // through to the default (per the option's contract) — callers cannot
85
+ // suppress the claim, only override its value.
86
+ const aud = options.aud ?? DEFAULT_JAR_AUDIENCE;
87
+ const lifetime = options.jarLifetimeSeconds ?? DEFAULT_JAR_LIFETIME_SECONDS;
88
+ const nowFn = options.now ?? (() => Math.floor(Date.now() / 1000));
89
+ const iat = nowFn();
90
+ const exp = iat + lifetime;
57
91
  try {
58
92
  // Spread into a fresh mutable object — `jose.SignJWT` wants
59
93
  // `JWTPayload` (mutable, index-signature) while `AuthorizationRequest`
60
94
  // is strict-readonly. The spread copies own enumerable props and
61
95
  // produces a value of structurally-compatible type without an
62
96
  // `as unknown as` double-cast.
97
+ //
98
+ // The OID4VP request fields go in first; if the caller has already
99
+ // set `aud`/`iat`/`exp` at the request level (unusual but legal),
100
+ // those payload-level values win. Otherwise we apply the resolved
101
+ // defaults below. Either way the JAR carries all three claims.
63
102
  const payload = { ...options.request };
103
+ if (payload["aud"] === undefined)
104
+ payload["aud"] = aud;
105
+ if (payload["iat"] === undefined)
106
+ payload["iat"] = iat;
107
+ if (payload["exp"] === undefined)
108
+ payload["exp"] = exp;
64
109
  const jwt = await new SignJWT(payload)
65
110
  .setProtectedHeader({
66
111
  alg: "ES256",
package/dist/jar.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jar.js","sourceRoot":"","sources":["../src/jar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EACL,WAAW,GAGZ,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAwC;IAExC,IACE,OAAO,CAAC,IAAI,KAAK,IAAI;QACrB,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;QAChC,OAAO,OAAO,CAAC,IAAI,CAAC,aAAa,KAAK,QAAQ,EAC9C,CAAC;QACD,MAAM,IAAI,WAAW,CACnB,2BAA2B,EAC3B,0DAA0D,CAC3D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,WAAW,CACnB,2BAA2B,EAC3B,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC;IACf,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,WAAW,CACnB,2BAA2B,EAC3B,2DACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,4DAA4D;QAC5D,uEAAuE;QACvE,iEAAiE;QACjE,8DAA8D;QAC9D,+BAA+B;QAC/B,MAAM,OAAO,GAA4B,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;aACnC,kBAAkB,CAAC;YAClB,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,qBAAqB;YAC1B,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;SAC3B,CAAC;aACD,IAAI,CAAC,UAAU,CAAC,CAAC;QACpB,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,WAAW,CACnB,2BAA2B,EAC3B,iDACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"jar.js","sourceRoot":"","sources":["../src/jar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Cryptographic randomness helpers for OID4VP authorization requests.
3
+ *
4
+ * Per OID4VP Final 1.0 §5.3 + §11.2 — verifier-supplied opaque values
5
+ * (`state`, `nonce`) MUST carry at least 128 bits of entropy. Even when
6
+ * holder binding (KB-JWT) is present, these fields are reused for CSRF
7
+ * stitching, replay protection and small values invite brute force in
8
+ * edge cases where the value leaks externally (e.g. via referer headers
9
+ * in poorly-implemented universal-link handling).
10
+ *
11
+ * Both helpers draw 16 random bytes (128 bits) from `node:crypto` and
12
+ * encode them in the form the spec prefers for that field:
13
+ *
14
+ * - `state` → hex (RFC 6648 implementation hint, also what the EU
15
+ * reference wallet's emulator build sends back verbatim — using hex
16
+ * keeps the value safe across URL-encoded transports).
17
+ * - `nonce` → base64url no-pad (matches what the wallet's KB-JWT
18
+ * `nonce` claim will echo, per OID4VP §5.5 + SD-JWT VC §4.3).
19
+ */
20
+ /**
21
+ * 128-bit random `state` value, hex-encoded.
22
+ *
23
+ * `state` is the verifier-controlled correlation token the wallet
24
+ * echoes back unchanged in the Authorization Response. Verifiers MUST
25
+ * generate this with enough entropy that a third party cannot guess a
26
+ * pending session id (OID4VP §5.3 + §11.2).
27
+ *
28
+ * 16 bytes → 128 bits → 32 hex chars. Use `generateNonce` for the
29
+ * cryptographic challenge in the same request — they serve different
30
+ * purposes and MUST NOT be reused for one another.
31
+ */
32
+ export declare function generateState(): string;
33
+ /**
34
+ * 128-bit random `nonce` value, base64url-encoded (no padding).
35
+ *
36
+ * `nonce` is the cryptographic challenge the wallet binds into its
37
+ * KB-JWT to prove possession of the holder key. It MUST be unique per
38
+ * request and at least 128 bits (OID4VP §5.3 + §11.2). 16 bytes →
39
+ * 128 bits → 22 base64url chars (no padding).
40
+ *
41
+ * Use `generateState` for the verifier's correlation token in the same
42
+ * request — they serve different purposes and MUST NOT be reused.
43
+ */
44
+ export declare function generateNonce(): string;
45
+ //# sourceMappingURL=random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
package/dist/random.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Cryptographic randomness helpers for OID4VP authorization requests.
3
+ *
4
+ * Per OID4VP Final 1.0 §5.3 + §11.2 — verifier-supplied opaque values
5
+ * (`state`, `nonce`) MUST carry at least 128 bits of entropy. Even when
6
+ * holder binding (KB-JWT) is present, these fields are reused for CSRF
7
+ * stitching, replay protection and small values invite brute force in
8
+ * edge cases where the value leaks externally (e.g. via referer headers
9
+ * in poorly-implemented universal-link handling).
10
+ *
11
+ * Both helpers draw 16 random bytes (128 bits) from `node:crypto` and
12
+ * encode them in the form the spec prefers for that field:
13
+ *
14
+ * - `state` → hex (RFC 6648 implementation hint, also what the EU
15
+ * reference wallet's emulator build sends back verbatim — using hex
16
+ * keeps the value safe across URL-encoded transports).
17
+ * - `nonce` → base64url no-pad (matches what the wallet's KB-JWT
18
+ * `nonce` claim will echo, per OID4VP §5.5 + SD-JWT VC §4.3).
19
+ */
20
+ import { randomBytes } from "node:crypto";
21
+ /**
22
+ * 128-bit random `state` value, hex-encoded.
23
+ *
24
+ * `state` is the verifier-controlled correlation token the wallet
25
+ * echoes back unchanged in the Authorization Response. Verifiers MUST
26
+ * generate this with enough entropy that a third party cannot guess a
27
+ * pending session id (OID4VP §5.3 + §11.2).
28
+ *
29
+ * 16 bytes → 128 bits → 32 hex chars. Use `generateNonce` for the
30
+ * cryptographic challenge in the same request — they serve different
31
+ * purposes and MUST NOT be reused for one another.
32
+ */
33
+ export function generateState() {
34
+ return randomBytes(16).toString("hex");
35
+ }
36
+ /**
37
+ * 128-bit random `nonce` value, base64url-encoded (no padding).
38
+ *
39
+ * `nonce` is the cryptographic challenge the wallet binds into its
40
+ * KB-JWT to prove possession of the holder key. It MUST be unique per
41
+ * request and at least 128 bits (OID4VP §5.3 + §11.2). 16 bytes →
42
+ * 128 bits → 22 base64url chars (no padding).
43
+ *
44
+ * Use `generateState` for the verifier's correlation token in the same
45
+ * request — they serve different purposes and MUST NOT be reused.
46
+ */
47
+ export function generateNonce() {
48
+ return randomBytes(16).toString("base64url");
49
+ }
50
+ //# sourceMappingURL=random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.js","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * `direct_post.jwt` response mode — OID4VP Final 1.0 §8.3.1, HAIP §5.1.
3
+ *
4
+ * Where `direct_post` sends the Authorization Response as plaintext
5
+ * `application/x-www-form-urlencoded`, `direct_post.jwt` wraps the
6
+ * exact same fields (`vp_token`, optional `presentation_submission`,
7
+ * `state`, `iss`) into a JSON object, then encrypts that object into
8
+ * a compact-serialised JWE keyed by the verifier's published
9
+ * encryption JWK. The JWE rides on a single form field named
10
+ * `response`.
11
+ *
12
+ * wallet ─ JSON encode vp_token + state + iss ──►
13
+ * ─ JWE-wrap with verifier.client_metadata.jwks[*].use="enc" ──►
14
+ * ─ form-encode as response=<JWE> ──►
15
+ * verifier
16
+ *
17
+ * verifier ─ extract `response` form param ──►
18
+ * ─ decrypt JWE with private encryption key ──►
19
+ * ─ JSON parse the cleartext payload ──►
20
+ * ─ feed into parseAuthorizationResponseBody equivalent ──►
21
+ *
22
+ * Why HAIP mandates this: with plaintext `direct_post` the PID claims
23
+ * (disclosed names, birthdates, addresses) travel as form fields the
24
+ * verifier's TLS terminator, reverse proxy, and downstream log
25
+ * pipelines can capture. Encrypting end-to-end (wallet → application)
26
+ * shrinks the trust boundary to the application that holds the
27
+ * private key.
28
+ *
29
+ * The crypto primitives used by default:
30
+ * - `alg = ECDH-ES` — direct ECDH-derived CEK, no extra key wrap.
31
+ * P-256 is the curve every HAIP wallet implements.
32
+ * - `enc = A256GCM` — authenticated encryption of the payload.
33
+ *
34
+ * Callers can opt into different `alg`/`enc` values via the options.
35
+ */
36
+ import type { JsonWebKey } from "@gramota/jose";
37
+ import { type AuthorizationResponse } from "./types.js";
38
+ /** Default JWE key-agreement algorithm — ECDH-ES, the option the EU
39
+ * reference wallet and HAIP §5.1 baseline implement. */
40
+ export declare const DEFAULT_RESPONSE_JWE_ALG = "ECDH-ES";
41
+ /** Default JWE content-encryption algorithm — A256GCM (authenticated). */
42
+ export declare const DEFAULT_RESPONSE_JWE_ENC = "A256GCM";
43
+ /**
44
+ * Generate a fresh JWE encryption keypair for the verifier.
45
+ *
46
+ * The public JWK goes into `client_metadata.jwks.keys[]` on the
47
+ * Authorization Request; the private JWK stays on the verifier and
48
+ * decrypts inbound `direct_post.jwt` responses.
49
+ *
50
+ * Returns both JWKs annotated with:
51
+ * - `use: "enc"` (RFC 7517 §4.2) so wallets can pick the right key
52
+ * when both signing and encryption keys are published
53
+ * - `alg`: the key-agreement algorithm (default ECDH-ES)
54
+ * - `kid` (optional, caller-supplied)
55
+ *
56
+ * Production deployments may want HSM-backed keys instead — the
57
+ * encryption keypair is a long-lived secret per verifier, not a
58
+ * per-request ephemeral. This generator is the development /
59
+ * pinned-trust path; the surface contract (JsonWebKey in and out) is
60
+ * the same regardless of where the bits come from.
61
+ */
62
+ export interface GenerateResponseEncryptionKeyOptions {
63
+ /** Key-agreement algorithm. Default `"ECDH-ES"`. */
64
+ readonly alg?: string;
65
+ /** Optional key id — written to both JWKs as `kid`. */
66
+ readonly kid?: string;
67
+ }
68
+ export declare function generateResponseEncryptionKey(options?: GenerateResponseEncryptionKeyOptions): Promise<{
69
+ publicJwk: JsonWebKey;
70
+ privateJwk: JsonWebKey;
71
+ }>;
72
+ export interface EncryptAuthorizationResponseOptions {
73
+ /** The Authorization Response to wrap. The same object you'd hand to
74
+ * `buildAuthorizationResponseBody` for `direct_post`. */
75
+ readonly response: AuthorizationResponse;
76
+ /** Verifier's encryption JWK — picked from `client_metadata.jwks`. */
77
+ readonly encryptionKey: JsonWebKey;
78
+ /** Optional override of the JWE `alg` header. Default
79
+ * {@link DEFAULT_RESPONSE_JWE_ALG} or `encryptionKey.alg` when set. */
80
+ readonly alg?: string;
81
+ /** Optional override of the JWE `enc` header. Default
82
+ * {@link DEFAULT_RESPONSE_JWE_ENC}. */
83
+ readonly enc?: string;
84
+ /** Optional override of the JWE `kid` header. Default
85
+ * `encryptionKey.kid`. */
86
+ readonly kid?: string;
87
+ }
88
+ /**
89
+ * Encrypt an Authorization Response per OID4VP §8.3.1.
90
+ *
91
+ * The cleartext is the JSON object the spec describes — same shape as
92
+ * the form-encoded `direct_post` body would carry, but as JSON rather
93
+ * than URL-encoded form. The output is a compact-serialised JWE
94
+ * suitable for the `response` form parameter of the wallet's POST to
95
+ * the verifier's `response_uri`.
96
+ *
97
+ * @throws {@link Oid4vpError} `oid4vp.response_encryption_failed`.
98
+ */
99
+ export declare function encryptAuthorizationResponse(options: EncryptAuthorizationResponseOptions): Promise<string>;
100
+ export interface DecryptAuthorizationResponseOptions {
101
+ /** The compact-serialised JWE pulled from the `response` form field. */
102
+ readonly jwe: string;
103
+ /** The verifier's private encryption JWK — counterpart to the public
104
+ * key published in `client_metadata.jwks`. */
105
+ readonly privateKey: JsonWebKey;
106
+ /** Optional allowlist of acceptable `enc` values. Default
107
+ * `["A256GCM"]` — narrow / widen for interop. */
108
+ readonly enc?: readonly string[];
109
+ /** Optional allowlist of acceptable `alg` values. Default
110
+ * `["ECDH-ES"]`. */
111
+ readonly alg?: readonly string[];
112
+ }
113
+ export interface DecryptedAuthorizationResponse {
114
+ /** The wallet's Authorization Response, ready to feed to the
115
+ * verifier's existing validation pipeline. */
116
+ readonly response: AuthorizationResponse;
117
+ /** The verified JWE protected header — `alg`, `enc`, `kid`. */
118
+ readonly header: Readonly<Record<string, unknown>>;
119
+ }
120
+ /**
121
+ * Decrypt a `direct_post.jwt` Authorization Response.
122
+ *
123
+ * Reverses {@link encryptAuthorizationResponse}: imports the private
124
+ * JWK, runs JWE compact-decrypt, JSON-parses the cleartext, validates
125
+ * shape (vp_token present, PEX path carries presentation_submission),
126
+ * and returns the {@link AuthorizationResponse}.
127
+ *
128
+ * The function enforces:
129
+ * - The JWE protected header `alg` is in the caller's allowlist
130
+ * (default `["ECDH-ES"]`).
131
+ * - The JWE protected header `enc` is in the caller's allowlist
132
+ * (default `["A256GCM"]`).
133
+ * - The cleartext is a JSON object (not an array, not bare string).
134
+ * - `vp_token` is present and is one of: string, string[], DCQL
135
+ * credential map.
136
+ * - PEX responses (string / string[]) carry `presentation_submission`;
137
+ * DCQL responses (object) need not.
138
+ *
139
+ * @throws {@link Oid4vpError} with codes
140
+ * `oid4vp.response_encryption_failed` (decryption / header rejection),
141
+ * `oid4vp.required_field_missing`, `oid4vp.invalid_value_type`,
142
+ * `oid4vp.malformed_body`, or `oid4vp.invalid_json`.
143
+ */
144
+ export declare function decryptAuthorizationResponse(options: DecryptAuthorizationResponseOptions): Promise<DecryptedAuthorizationResponse>;
145
+ //# sourceMappingURL=response-jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-jwt.d.ts","sourceRoot":"","sources":["../src/response-jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAe,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAErE;wDACwD;AACxD,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,0EAA0E;AAC1E,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,oCAAoC;IACnD,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,6BAA6B,CACjD,OAAO,GAAE,oCAAyC,GACjD,OAAO,CAAC;IAAE,SAAS,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC,CAwB5D;AAMD,MAAM,WAAW,mCAAmC;IAClD;6DACyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,sEAAsE;IACtE,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC;2EACuE;IACvE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;2CACuC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;8BAC0B;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,MAAM,CAAC,CA2DjB;AA2BD,MAAM,WAAW,mCAAmC;IAClD,wEAAwE;IACxE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;kDAC8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;qDACiD;IACjD,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;wBACoB;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,8BAA8B;IAC7C;kDAC8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,8BAA8B,CAAC,CA0HzC"}
@@ -0,0 +1,295 @@
1
+ /**
2
+ * `direct_post.jwt` response mode — OID4VP Final 1.0 §8.3.1, HAIP §5.1.
3
+ *
4
+ * Where `direct_post` sends the Authorization Response as plaintext
5
+ * `application/x-www-form-urlencoded`, `direct_post.jwt` wraps the
6
+ * exact same fields (`vp_token`, optional `presentation_submission`,
7
+ * `state`, `iss`) into a JSON object, then encrypts that object into
8
+ * a compact-serialised JWE keyed by the verifier's published
9
+ * encryption JWK. The JWE rides on a single form field named
10
+ * `response`.
11
+ *
12
+ * wallet ─ JSON encode vp_token + state + iss ──►
13
+ * ─ JWE-wrap with verifier.client_metadata.jwks[*].use="enc" ──►
14
+ * ─ form-encode as response=<JWE> ──►
15
+ * verifier
16
+ *
17
+ * verifier ─ extract `response` form param ──►
18
+ * ─ decrypt JWE with private encryption key ──►
19
+ * ─ JSON parse the cleartext payload ──►
20
+ * ─ feed into parseAuthorizationResponseBody equivalent ──►
21
+ *
22
+ * Why HAIP mandates this: with plaintext `direct_post` the PID claims
23
+ * (disclosed names, birthdates, addresses) travel as form fields the
24
+ * verifier's TLS terminator, reverse proxy, and downstream log
25
+ * pipelines can capture. Encrypting end-to-end (wallet → application)
26
+ * shrinks the trust boundary to the application that holds the
27
+ * private key.
28
+ *
29
+ * The crypto primitives used by default:
30
+ * - `alg = ECDH-ES` — direct ECDH-derived CEK, no extra key wrap.
31
+ * P-256 is the curve every HAIP wallet implements.
32
+ * - `enc = A256GCM` — authenticated encryption of the payload.
33
+ *
34
+ * Callers can opt into different `alg`/`enc` values via the options.
35
+ */
36
+ import { CompactEncrypt, compactDecrypt, exportJWK, generateKeyPair, importJWK } from "jose";
37
+ import { Oid4vpError } from "./types.js";
38
+ /** Default JWE key-agreement algorithm — ECDH-ES, the option the EU
39
+ * reference wallet and HAIP §5.1 baseline implement. */
40
+ export const DEFAULT_RESPONSE_JWE_ALG = "ECDH-ES";
41
+ /** Default JWE content-encryption algorithm — A256GCM (authenticated). */
42
+ export const DEFAULT_RESPONSE_JWE_ENC = "A256GCM";
43
+ export async function generateResponseEncryptionKey(options = {}) {
44
+ const alg = options.alg ?? DEFAULT_RESPONSE_JWE_ALG;
45
+ let keys;
46
+ try {
47
+ keys = await generateKeyPair(alg, { extractable: true });
48
+ }
49
+ catch (err) {
50
+ throw new Oid4vpError("oid4vp.cert_generation_failed", `generateResponseEncryptionKey: alg ${JSON.stringify(alg)} not supported: ${err instanceof Error ? err.message : String(err)}`);
51
+ }
52
+ const publicJwk = (await exportJWK(keys.publicKey));
53
+ const privateJwk = (await exportJWK(keys.privateKey));
54
+ publicJwk.use = "enc";
55
+ privateJwk.use = "enc";
56
+ publicJwk.alg = alg;
57
+ privateJwk.alg = alg;
58
+ if (options.kid !== undefined) {
59
+ publicJwk.kid = options.kid;
60
+ privateJwk.kid = options.kid;
61
+ }
62
+ return { publicJwk, privateJwk };
63
+ }
64
+ /**
65
+ * Encrypt an Authorization Response per OID4VP §8.3.1.
66
+ *
67
+ * The cleartext is the JSON object the spec describes — same shape as
68
+ * the form-encoded `direct_post` body would carry, but as JSON rather
69
+ * than URL-encoded form. The output is a compact-serialised JWE
70
+ * suitable for the `response` form parameter of the wallet's POST to
71
+ * the verifier's `response_uri`.
72
+ *
73
+ * @throws {@link Oid4vpError} `oid4vp.response_encryption_failed`.
74
+ */
75
+ export async function encryptAuthorizationResponse(options) {
76
+ if (options.encryptionKey === null ||
77
+ typeof options.encryptionKey !== "object") {
78
+ throw new Oid4vpError("oid4vp.response_encryption_failed", "encryptAuthorizationResponse: encryptionKey is required");
79
+ }
80
+ const alg = options.alg ??
81
+ (typeof options.encryptionKey.alg === "string"
82
+ ? options.encryptionKey.alg
83
+ : DEFAULT_RESPONSE_JWE_ALG);
84
+ const enc = options.enc ?? DEFAULT_RESPONSE_JWE_ENC;
85
+ const payload = buildJwtResponsePayload(options.response);
86
+ let publicKey;
87
+ try {
88
+ publicKey = await importJWK(options.encryptionKey, alg);
89
+ }
90
+ catch (err) {
91
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `encryptAuthorizationResponse: failed to import encryption JWK: ${err instanceof Error ? err.message : String(err)}`);
92
+ }
93
+ const protectedHeader = { alg, enc };
94
+ const kid = options.kid ??
95
+ (typeof options.encryptionKey.kid === "string"
96
+ ? options.encryptionKey.kid
97
+ : undefined);
98
+ if (kid !== undefined)
99
+ protectedHeader["kid"] = kid;
100
+ try {
101
+ const cleartext = new TextEncoder().encode(JSON.stringify(payload));
102
+ return await new CompactEncrypt(cleartext)
103
+ .setProtectedHeader(protectedHeader)
104
+ .encrypt(publicKey);
105
+ }
106
+ catch (err) {
107
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `encryptAuthorizationResponse: JWE encryption failed: ${err instanceof Error ? err.message : String(err)}`);
108
+ }
109
+ }
110
+ /** Convert an AuthorizationResponse to the JSON object that
111
+ * `direct_post.jwt` ships as the JWE cleartext.
112
+ *
113
+ * The JWE cleartext is conceptually the same as the `direct_post`
114
+ * form body, except parameters are JSON-typed (no URL encoding /
115
+ * string coercion), and complex values (vp_token map, submission
116
+ * map) are nested as objects rather than embedded as JSON-string
117
+ * fields. This mirrors what production EU wallets send.
118
+ */
119
+ function buildJwtResponsePayload(response) {
120
+ const out = { vp_token: response.vp_token };
121
+ if (response.presentation_submission !== undefined) {
122
+ out["presentation_submission"] = response.presentation_submission;
123
+ }
124
+ if (response.state !== undefined)
125
+ out["state"] = response.state;
126
+ if (response.iss !== undefined)
127
+ out["iss"] = response.iss;
128
+ return out;
129
+ }
130
+ /**
131
+ * Decrypt a `direct_post.jwt` Authorization Response.
132
+ *
133
+ * Reverses {@link encryptAuthorizationResponse}: imports the private
134
+ * JWK, runs JWE compact-decrypt, JSON-parses the cleartext, validates
135
+ * shape (vp_token present, PEX path carries presentation_submission),
136
+ * and returns the {@link AuthorizationResponse}.
137
+ *
138
+ * The function enforces:
139
+ * - The JWE protected header `alg` is in the caller's allowlist
140
+ * (default `["ECDH-ES"]`).
141
+ * - The JWE protected header `enc` is in the caller's allowlist
142
+ * (default `["A256GCM"]`).
143
+ * - The cleartext is a JSON object (not an array, not bare string).
144
+ * - `vp_token` is present and is one of: string, string[], DCQL
145
+ * credential map.
146
+ * - PEX responses (string / string[]) carry `presentation_submission`;
147
+ * DCQL responses (object) need not.
148
+ *
149
+ * @throws {@link Oid4vpError} with codes
150
+ * `oid4vp.response_encryption_failed` (decryption / header rejection),
151
+ * `oid4vp.required_field_missing`, `oid4vp.invalid_value_type`,
152
+ * `oid4vp.malformed_body`, or `oid4vp.invalid_json`.
153
+ */
154
+ export async function decryptAuthorizationResponse(options) {
155
+ if (typeof options.jwe !== "string" || options.jwe.length === 0) {
156
+ throw new Oid4vpError("oid4vp.required_field_missing", "decryptAuthorizationResponse: jwe is required");
157
+ }
158
+ if (options.privateKey === null ||
159
+ typeof options.privateKey !== "object") {
160
+ throw new Oid4vpError("oid4vp.response_encryption_failed", "decryptAuthorizationResponse: privateKey is required");
161
+ }
162
+ const allowedAlgs = options.alg ?? [DEFAULT_RESPONSE_JWE_ALG];
163
+ const allowedEncs = options.enc ?? [DEFAULT_RESPONSE_JWE_ENC];
164
+ // Pre-flight header inspection — the JWE library will also reject
165
+ // out-of-allowlist algs once we pass keyManagementAlgorithms /
166
+ // contentEncryptionAlgorithms, but we want spec-quality errors with
167
+ // our stable codes, so we look at the header explicitly first.
168
+ const segments = options.jwe.split(".");
169
+ if (segments.length !== 5) {
170
+ throw new Oid4vpError("oid4vp.malformed_body", "decryptAuthorizationResponse: malformed JWE (compact serialisation has 5 segments)");
171
+ }
172
+ let header;
173
+ try {
174
+ const json = Buffer.from(segments[0], "base64url").toString("utf-8");
175
+ const parsed = JSON.parse(json);
176
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
177
+ throw new Error("JWE header is not a JSON object");
178
+ }
179
+ header = parsed;
180
+ }
181
+ catch (err) {
182
+ throw new Oid4vpError("oid4vp.malformed_body", `decryptAuthorizationResponse: malformed JWE header: ${err instanceof Error ? err.message : String(err)}`);
183
+ }
184
+ const headerAlg = header["alg"];
185
+ const headerEnc = header["enc"];
186
+ if (typeof headerAlg !== "string" ||
187
+ !allowedAlgs.includes(headerAlg)) {
188
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `decryptAuthorizationResponse: JWE alg ${JSON.stringify(headerAlg)} is not in allowlist (${allowedAlgs.join(", ")})`);
189
+ }
190
+ if (typeof headerEnc !== "string" ||
191
+ !allowedEncs.includes(headerEnc)) {
192
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `decryptAuthorizationResponse: JWE enc ${JSON.stringify(headerEnc)} is not in allowlist (${allowedEncs.join(", ")})`);
193
+ }
194
+ let privateKey;
195
+ try {
196
+ privateKey = await importJWK(options.privateKey, headerAlg);
197
+ }
198
+ catch (err) {
199
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `decryptAuthorizationResponse: failed to import private JWK: ${err instanceof Error ? err.message : String(err)}`);
200
+ }
201
+ let plaintextBytes;
202
+ try {
203
+ const decrypted = await compactDecrypt(options.jwe, privateKey, {
204
+ keyManagementAlgorithms: [...allowedAlgs],
205
+ contentEncryptionAlgorithms: [...allowedEncs],
206
+ });
207
+ plaintextBytes = decrypted.plaintext;
208
+ }
209
+ catch (err) {
210
+ throw new Oid4vpError("oid4vp.response_encryption_failed", `decryptAuthorizationResponse: JWE decryption failed: ${err instanceof Error ? err.message : String(err)}`);
211
+ }
212
+ let body;
213
+ try {
214
+ const json = new TextDecoder().decode(plaintextBytes);
215
+ const parsed = JSON.parse(json);
216
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
217
+ throw new Error("response payload is not a JSON object");
218
+ }
219
+ body = parsed;
220
+ }
221
+ catch (err) {
222
+ throw new Oid4vpError("oid4vp.invalid_json", `decryptAuthorizationResponse: cleartext is not a JSON object: ${err instanceof Error ? err.message : String(err)}`);
223
+ }
224
+ const response = parseJwtResponsePayload(body);
225
+ return { response, header };
226
+ }
227
+ /** Convert the JWE cleartext (already parsed as a JSON object) into an
228
+ * AuthorizationResponse. The shape constraints mirror those enforced
229
+ * by `parseAuthorizationResponseFromParams` for the form-encoded path.
230
+ */
231
+ function parseJwtResponsePayload(body) {
232
+ const vpTokenRaw = body["vp_token"];
233
+ if (vpTokenRaw === undefined) {
234
+ throw new Oid4vpError("oid4vp.required_field_missing", "Authorization Response is missing required parameter: vp_token");
235
+ }
236
+ let vp_token;
237
+ if (typeof vpTokenRaw === "string") {
238
+ vp_token = vpTokenRaw;
239
+ }
240
+ else if (Array.isArray(vpTokenRaw) &&
241
+ vpTokenRaw.every((v) => typeof v === "string")) {
242
+ vp_token = vpTokenRaw;
243
+ }
244
+ else if (vpTokenRaw !== null &&
245
+ typeof vpTokenRaw === "object" &&
246
+ !Array.isArray(vpTokenRaw)) {
247
+ // DCQL credential map — keys are credential ids. Some wallets wrap
248
+ // each value in a single-element array (mirroring multi-instance
249
+ // presentation futures); flatten to match the form-encoded path.
250
+ const obj = vpTokenRaw;
251
+ const flat = {};
252
+ for (const [id, val] of Object.entries(obj)) {
253
+ if (typeof val === "string") {
254
+ flat[id] = val;
255
+ }
256
+ else if (Array.isArray(val) &&
257
+ val.length === 1 &&
258
+ typeof val[0] === "string") {
259
+ flat[id] = val[0];
260
+ }
261
+ else {
262
+ throw new Oid4vpError("oid4vp.invalid_value_type", `vp_token[${id}] must be a string or single-element array of strings`);
263
+ }
264
+ }
265
+ vp_token = flat;
266
+ }
267
+ else {
268
+ throw new Oid4vpError("oid4vp.invalid_value_type", "vp_token must be a string, array of strings, or DCQL credential map");
269
+ }
270
+ const isDcqlResponse = typeof vp_token === "object" && !Array.isArray(vp_token);
271
+ let submission;
272
+ const submissionRaw = body["presentation_submission"];
273
+ if (submissionRaw !== undefined) {
274
+ if (submissionRaw === null ||
275
+ typeof submissionRaw !== "object" ||
276
+ Array.isArray(submissionRaw)) {
277
+ throw new Oid4vpError("oid4vp.malformed_submission", "presentation_submission must be a JSON object (DIF Presentation Exchange v2)");
278
+ }
279
+ submission = submissionRaw;
280
+ }
281
+ else if (!isDcqlResponse) {
282
+ throw new Oid4vpError("oid4vp.required_field_missing", "Authorization Response is missing required parameter: presentation_submission");
283
+ }
284
+ const result = { vp_token };
285
+ if (submission !== undefined)
286
+ result.presentation_submission = submission;
287
+ const state = body["state"];
288
+ if (typeof state === "string")
289
+ result.state = state;
290
+ const iss = body["iss"];
291
+ if (typeof iss === "string")
292
+ result.iss = iss;
293
+ return result;
294
+ }
295
+ //# sourceMappingURL=response-jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-jwt.js","sourceRoot":"","sources":["../src/response-jwt.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -7,8 +7,12 @@ import { GramotaError } from "@gramota/core";
7
7
  * Presentation Definition (§5.4) is modelled but not yet matched/queried —
8
8
  * downstream packages will add DIF Presentation Exchange JSONPath support.
9
9
  */
10
- /** OID4VP §5.4 — `client_id_scheme` enumerated values. */
11
- export type ClientIdScheme = "pre-registered" | "redirect_uri" | "https" | "did" | "x509_san_dns" | "x509_san_uri" | "verifier_attestation" | (string & {});
10
+ /** OID4VP §5.4 + §5.9.3 / HAIP Final 1.0 §5 — `client_id_scheme`
11
+ * enumerated values. HAIP Final 1.0 mandates `x509_hash` for
12
+ * production verifiers; `x509_san_dns` is the legacy prefix the EU
13
+ * reference wallet's emulator build still accepts, kept here for
14
+ * back-compat during the transition. */
15
+ export type ClientIdScheme = "pre-registered" | "redirect_uri" | "https" | "did" | "x509_san_dns" | "x509_san_uri" | "x509_hash" | "verifier_attestation" | (string & {});
12
16
  /** OID4VP §6.2 — `response_mode` for the authorization response. */
13
17
  export type ResponseMode = "direct_post" | "direct_post.jwt" | "fragment" | "query";
14
18
  /** OID4VP §5 — Authorization Request, the bundle a verifier sends to a wallet.
@@ -108,7 +112,7 @@ export interface SigningCert {
108
112
  readonly sanDns: string;
109
113
  }
110
114
  /** Stable codes for `Oid4vpError`. */
111
- export type Oid4vpErrorCode = "oid4vp.invalid_url" | "oid4vp.required_field_missing" | "oid4vp.unsupported_response_type" | "oid4vp.mutually_exclusive_fields" | "oid4vp.response_uri_required" | "oid4vp.invalid_json" | "oid4vp.invalid_value_type" | "oid4vp.malformed_body" | "oid4vp.malformed_submission" | "oid4vp.cert_generation_failed" | "oid4vp.jar_signing_failed";
115
+ export type Oid4vpErrorCode = "oid4vp.invalid_url" | "oid4vp.required_field_missing" | "oid4vp.unsupported_response_type" | "oid4vp.mutually_exclusive_fields" | "oid4vp.response_uri_required" | "oid4vp.invalid_json" | "oid4vp.invalid_value_type" | "oid4vp.malformed_body" | "oid4vp.malformed_submission" | "oid4vp.cert_generation_failed" | "oid4vp.jar_signing_failed" | "oid4vp.response_encryption_failed";
112
116
  export declare class Oid4vpError extends GramotaError {
113
117
  readonly code: Oid4vpErrorCode;
114
118
  constructor(code: Oid4vpErrorCode, message: string, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;GAOG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,cAAc,GACd,OAAO,GACP,KAAK,GACL,cAAc,GACd,cAAc,GACd,sBAAsB,GACtB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,oEAAoE;AACpE,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,iBAAiB,GACjB,UAAU,GACV,OAAO,CAAC;AAEZ;;;;2DAI2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,aAAa,EAAE,UAAU,CAAC;IAC1B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB;uEACmE;IACnE,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC,wEAAwE;IACxE,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;mCAC+B;IAC/B,uBAAuB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,gFAAgF;IAChF,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;4DACwD;IACxD,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD;+BAC2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE;gEAC4D;IAC5D,uBAAuB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;sEACkE;IAClE,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;2CAEuC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,sCAAsC;AACtC,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,GAClC,8BAA8B,GAC9B,qBAAqB,GACrB,2BAA2B,GAC3B,uBAAuB,GACvB,6BAA6B,GAC7B,+BAA+B,GAC/B,2BAA2B,CAAC;AAEhC,qBAAa,WAAY,SAAQ,YAAY;IAC3C,SAAkB,IAAI,EAAE,eAAe,CAAC;gBAGtC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAMhC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;GAOG;AAEH;;;;wCAIwC;AACxC,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,cAAc,GACd,OAAO,GACP,KAAK,GACL,cAAc,GACd,cAAc,GACd,WAAW,GACX,sBAAsB,GACtB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,oEAAoE;AACpE,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,iBAAiB,GACjB,UAAU,GACV,OAAO,CAAC;AAEZ;;;;2DAI2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,aAAa,EAAE,UAAU,CAAC;IAC1B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB;uEACmE;IACnE,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC,wEAAwE;IACxE,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;mCAC+B;IAC/B,uBAAuB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,gFAAgF;IAChF,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;4DACwD;IACxD,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD;+BAC2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE;gEAC4D;IAC5D,uBAAuB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;sEACkE;IAClE,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;2CAEuC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,sCAAsC;AACtC,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,GAClC,8BAA8B,GAC9B,qBAAqB,GACrB,2BAA2B,GAC3B,uBAAuB,GACvB,6BAA6B,GAC7B,+BAA+B,GAC/B,2BAA2B,GAC3B,mCAAmC,CAAC;AAExC,qBAAa,WAAY,SAAQ,YAAY;IAC3C,SAAkB,IAAI,EAAE,eAAe,CAAC;gBAGtC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAMhC"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AA8I7C,MAAM,OAAO,WAAY,SAAQ,YAAY;IACzB,IAAI,CAAkB;IAExC,YACE,IAAqB,EACrB,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAoJ7C,MAAM,OAAO,WAAY,SAAQ,YAAY;IACzB,IAAI,CAAkB;IAExC,YACE,IAAqB,EACrB,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gramota/oid4vp",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "OpenID for Verifiable Presentations transport — authorization request/response wire format for EUDIW.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -19,8 +19,8 @@
19
19
  "@peculiar/x509": "^2.0.0",
20
20
  "jose": "^5.9.6",
21
21
  "reflect-metadata": "^0.2.0",
22
- "@gramota/core": "0.2.0",
23
- "@gramota/jose": "0.2.1"
22
+ "@gramota/core": "0.2.1",
23
+ "@gramota/jose": "0.3.0"
24
24
  },
25
25
  "sideEffects": [
26
26
  "./dist/cert.js"