1
1
import { JWKS , JWK } from "../../utils/jwk" ;
2
2
import { hasStatusOrThrow } from "../../utils/misc" ;
3
3
import { RelyingPartyEntityConfiguration } from "../../entity/trust/types" ;
4
+ import { decode as decodeJwt } from "@pagopa/io-react-native-jwt" ;
5
+ import { NoSuitableKeysFoundInEntityConfiguration } from "./errors" ;
4
6
5
7
/**
6
8
* Defines the signature for a function that retrieves JSON Web Key Sets (JWKS) from a client.
@@ -15,35 +17,53 @@ export type FetchJwks<T extends Array<unknown> = []> = (...args: T) => Promise<{
15
17
16
18
/**
17
19
* Retrieves the JSON Web Key Set (JWKS) from the specified client's well-known endpoint.
20
+ * It is formed using `{issUrl.base}/.well-known/jar-issuer${issUrl.pah}` as explained in SD-JWT VC issuer metadata section
18
21
*
19
- * @param clientUrl - The base URL of the client entity from which to retrieve the JWKS .
22
+ * @param requestObjectEncodedJwt - Request Object in JWT format .
20
23
* @param options - Optional context containing a custom fetch implementation.
21
24
* @param options.context - Optional context object.
22
25
* @param options.context.appFetch - Optional custom fetch function to use instead of the global `fetch`.
23
26
* @returns A promise resolving to an object containing an array of JWKs.
24
27
* @throws Will throw an error if the JWKS retrieval fails.
25
28
*/
26
- export const fetchJwksFromUri : FetchJwks <
29
+ export const fetchJwksFromRequestObject : FetchJwks <
27
30
[ string , { context ?: { appFetch ?: GlobalFetch [ "fetch" ] } } ]
28
- > = async ( clientUrl , { context = { } } = { } ) => {
31
+ > = async ( requestObjectEncodedJwt , { context = { } } = { } ) => {
29
32
const { appFetch = fetch } = context ;
33
+ const requestObjectJwt = decodeJwt ( requestObjectEncodedJwt ) ;
30
34
31
- const wellKnownUrl = new URL (
32
- "/.well-known/jar-issuer/jwk" ,
33
- clientUrl
34
- ) . toString ( ) ;
35
+ // 1. check if request object jwt contains the 'jwk' attribute
36
+ if ( requestObjectJwt . protectedHeader ?. jwk ) {
37
+ return {
38
+ keys : [ JWK . parse ( requestObjectJwt . protectedHeader . jwk ) ] ,
39
+ } ;
40
+ }
35
41
36
- // Fetches the JWKS from a specific endpoint of the entity's well-known configuration
37
- const jwks = await appFetch ( wellKnownUrl , {
38
- method : "GET" ,
39
- } )
40
- . then ( hasStatusOrThrow ( 200 ) )
41
- . then ( ( raw ) => raw . json ( ) )
42
- . then ( ( json ) => JWKS . parse ( json ) ) ;
42
+ // 2. According to Potential profile, retrieve from RP endpoint using iss claim
43
+ const issClaimValue = requestObjectJwt . payload ?. iss as string ;
44
+ if ( issClaimValue ) {
45
+ const issUrl = new URL ( issClaimValue ) ;
46
+ const wellKnownUrl = new URL (
47
+ `/.well-known/jar-issuer${ issUrl . pathname } ` ,
48
+ `${ issUrl . protocol } //${ issUrl . host } `
49
+ ) . toString ( ) ;
43
50
44
- return {
45
- keys : jwks . keys ,
46
- } ;
51
+ // Fetches the JWKS from a specific endpoint of the entity's well-known configuration
52
+ const jwks = await appFetch ( wellKnownUrl , {
53
+ method : "GET" ,
54
+ } )
55
+ . then ( hasStatusOrThrow ( 200 ) )
56
+ . then ( ( raw ) => raw . json ( ) )
57
+ . then ( ( json ) => JWKS . parse ( json . jwks ) ) ;
58
+
59
+ return {
60
+ keys : jwks . keys ,
61
+ } ;
62
+ }
63
+
64
+ throw new NoSuitableKeysFoundInEntityConfiguration (
65
+ "Request Object signature verification"
66
+ ) ;
47
67
} ;
48
68
49
69
/**
@@ -54,14 +74,9 @@ export const fetchJwksFromUri: FetchJwks<
54
74
* @throws Will throw an error if the configuration is invalid or if JWKS is not found.
55
75
*/
56
76
export const fetchJwksFromConfig : FetchJwks <
57
- [ RelyingPartyEntityConfiguration ]
77
+ [ RelyingPartyEntityConfiguration [ "payload" ] [ "metadata" ] ]
58
78
> = async ( rpConfig ) => {
59
- const parsedConfig = RelyingPartyEntityConfiguration . safeParse ( rpConfig ) ;
60
- if ( ! parsedConfig . success ) {
61
- throw new Error ( "Invalid Relying Party configuration." ) ;
62
- }
63
-
64
- const jwks = parsedConfig . data . payload . metadata . wallet_relying_party . jwks ;
79
+ const jwks = rpConfig . wallet_relying_party . jwks ;
65
80
66
81
if ( ! jwks || ! Array . isArray ( jwks . keys ) ) {
67
82
throw new Error ( "JWKS not found in Relying Party configuration." ) ;
0 commit comments