@sphereon/ssi-sdk-ext.jwt-service 0.24.1-unstable.93 → 0.25.1-feature.SDK.41.oidf.support.11

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.
@@ -1,113 +1,332 @@
1
- import { IIdentifierResolution, ManagedIdentifierOptsOrResult, ManagedIdentifierResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
2
- import { ISphereonKeyManager } from '@sphereon/ssi-sdk-ext.key-manager'
3
- import { JWK, SignatureAlgorithmJwa } from '@sphereon/ssi-sdk-ext.key-utils'
4
- import { IAgentContext, IPluginMethodMap } from '@veramo/core'
1
+ import {
2
+ ExternalIdentifierDidOpts,
3
+ ExternalIdentifierResult,
4
+ ExternalIdentifierX5cOpts,
5
+ IIdentifierResolution,
6
+ ManagedIdentifierOptsOrResult,
7
+ ManagedIdentifierResult,
8
+ } from '@sphereon/ssi-sdk-ext.identifier-resolution'
9
+ import {ClientIdScheme} from '@sphereon/ssi-sdk-ext.x509-utils'
10
+ import {
11
+ BaseJWK,
12
+ IValidationResult,
13
+ JoseSignatureAlgorithm,
14
+ JoseSignatureAlgorithmString,
15
+ JWK
16
+ } from '@sphereon/ssi-types'
17
+ import {IAgentContext, IKeyManager, IPluginMethodMap} from '@veramo/core'
18
+
19
+ export type IRequiredContext = IAgentContext<IIdentifierResolution & IKeyManager> // could we still interop with Veramo?
20
+
21
+ export const jwtServiceContextMethods: Array<string> = [
22
+ 'jwtPrepareJws',
23
+ 'jwtCreateJwsJsonGeneralSignature',
24
+ 'jwtCreateJwsJsonFlattenedSignature',
25
+ 'jwtCreateJwsCompactSignature',
26
+ 'jwtVerifyJwsSignature',
27
+ 'jwtEncryptJweCompactJwt',
28
+ 'jwtDecryptJweCompactJwt'
29
+ ]
5
30
 
6
- export type IRequiredContext = IAgentContext<IIdentifierResolution & ISphereonKeyManager> // could we still interop with Veramo?
7
31
  export interface IJwtService extends IPluginMethodMap {
8
- jwtPrepareJws(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<PreparedJwsObject>
32
+ jwtPrepareJws(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<PreparedJwsObject>
33
+
34
+ jwtCreateJwsJsonGeneralSignature(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<JwsJsonGeneral>
35
+
36
+ jwtCreateJwsJsonFlattenedSignature(args: CreateJwsFlattenedArgs, context: IRequiredContext): Promise<JwsJsonFlattened>
37
+
38
+ jwtCreateJwsCompactSignature(args: CreateJwsCompactArgs, context: IRequiredContext): Promise<JwtCompactResult>
9
39
 
10
- jwtCreateJwsJsonGeneralSignature(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<JwsJsonGeneral>
40
+ jwtVerifyJwsSignature(args: VerifyJwsArgs, context: IRequiredContext): Promise<IJwsValidationResult>
11
41
 
12
- jwtCreateJwsJsonFlattenedSignature(args: CreateJwsFlattenedArgs, context: IRequiredContext): Promise<JwsJsonFlattened>
42
+ jwtEncryptJweCompactJwt(args: EncryptJweCompactJwtArgs, context: IRequiredContext): Promise<JwtCompactResult>
13
43
 
14
- jwtCreateJwsCompactSignature(args: CreateJwsCompactArgs, context: IRequiredContext): Promise<JwsCompactResult>
44
+ jwtDecryptJweCompactJwt(args: DecryptJweCompactJwtArgs, context: IRequiredContext): Promise<JwtCompactResult>
15
45
 
16
- // jwtVerifyJwsCompactSignature(args: {jwt: string}): Promise<any>
46
+ // TODO: JWE/encryption general methods
47
+ }
17
48
 
18
- // TODO: JWE/encryption
49
+ export type IJwsValidationResult = IValidationResult & {
50
+ jws: JwsJsonGeneralWithIdentifiers // We always translate to general as that is the most flexible format allowing multiple sigs
51
+
19
52
  }
20
53
 
21
54
  export interface PreparedJws {
22
- protectedHeader: JwtHeader
23
- payload: Uint8Array
24
- unprotectedHeader?: JwtHeader // only for jws json and also then optional
25
- existingSignatures?: Array<JwsJsonSignature> // only for jws json and also then optional
55
+ protectedHeader: JwsHeader
56
+ payload: Uint8Array
57
+ unprotectedHeader?: JwsHeader // only for jws json and also then optional
58
+ existingSignatures?: Array<JwsJsonSignature> // only for jws json and also then optional
26
59
  }
27
60
 
28
61
  export interface JwsJsonSignature {
29
- protected: string
30
- header?: JwtHeader
31
- signature: string
62
+ protected: string
63
+ header?: JwsHeader
64
+ signature: string
65
+ }
66
+
67
+ /**
68
+ * The JWK representation of an ephemeral public key.
69
+ * See https://www.rfc-editor.org/rfc/rfc7518.html#section-6
70
+ */
71
+ // todo split into separate objects
72
+ export type EphemeralPublicKey = Omit<BaseJWK, 'alg'>
73
+
74
+ // export function isEcJWK(v)
75
+
76
+ export interface JweHeader extends Omit<BaseJwtHeader, 'alg'> {
77
+ alg: string,
78
+ enc: string,
79
+ jku?: string,
80
+ jwk?: BaseJWK,
81
+ epk?: EphemeralPublicKey,
82
+ x5u?: string
83
+ x5c?: string[]
84
+ x5t?: string,
85
+ cty?: string,
86
+ crit?: string[]
87
+
88
+ [k: string]: any
89
+
90
+ }
91
+
92
+
93
+ export interface JweRecipientUnprotectedHeader {
94
+ alg: string
95
+ iv: string
96
+ tag: string
97
+ epk?: EphemeralPublicKey
98
+ kid?: string
99
+ apv?: string
100
+ apu?: string
101
+ }
102
+
103
+ export interface JweProtectedHeader extends Partial<JweHeader> {
104
+ zip?: 'DEF' | string
32
105
  }
33
106
 
107
+
108
+ export type Jws = JwsCompact | JwsJsonFlattened | JwsJsonGeneral
109
+
34
110
  export type JwsCompact = string
35
111
 
36
112
  export interface JwsJsonFlattened {
37
- payload: string
38
- protected: string
39
- header?: JwtHeader
40
- signature: string
113
+ payload: string
114
+ protected: string
115
+ header?: JwsHeader
116
+ signature: string
41
117
  }
42
118
 
43
119
  export interface JwsJsonGeneral {
44
- payload: string
45
- signatures: Array<JwsJsonSignature>
120
+ payload: string
121
+ signatures: Array<JwsJsonSignature>
122
+ }
123
+
124
+ export interface JwsJsonGeneralWithIdentifiers extends JwsJsonGeneral {
125
+ signatures: Array<JwsJsonSignatureWithIdentifier>
126
+ }
127
+
128
+ export interface JwsJsonSignatureWithIdentifier extends JwsJsonSignature {
129
+ identifier: ExternalIdentifierResult
130
+ publicKeyHex: string
131
+ }
132
+
133
+
134
+ export type Jwe = JweCompact | JweJsonFlattened | JweJsonGeneral
135
+ export type JweCompact = string
136
+
137
+ export interface JweJsonFlattened {
138
+ protected: string
139
+ unprotected: JweHeader
140
+ header: JweHeader | JweRecipientUnprotectedHeader
141
+ encrypted_key?: string
142
+ aad?: string
143
+ iv: string
144
+ ciphertext: string
145
+ tag?: string
46
146
  }
47
147
 
148
+
149
+ export interface JweRecipient {
150
+ header?: JweRecipientUnprotectedHeader
151
+ encrypted_key?: string
152
+ }
153
+
154
+ export interface JweJsonGeneral {
155
+ protected: string
156
+ unprotected?: JweHeader
157
+ recipients: Array<JweRecipient>
158
+ aad?: string
159
+ iv: string
160
+ ciphertext: string
161
+ tag?: string
162
+ }
163
+
164
+
48
165
  export interface PreparedJwsObject {
49
- jws: PreparedJws
50
- b64: { payload: string; protectedHeader: string } // header is always json, as it can only be used in JwsJson
51
- identifier: ManagedIdentifierResult
166
+ jws: PreparedJws
167
+ b64: { payload: string; protectedHeader: string } // header is always json, as it can only be used in JwsJson
168
+ identifier: ManagedIdentifierResult
52
169
  }
53
170
 
54
171
  export interface BaseJwtHeader {
55
- typ?: string
56
- alg?: string
57
- kid?: string
172
+ typ?: string
173
+ alg?: string
174
+ kid?: string
58
175
  }
176
+
59
177
  export interface BaseJwtPayload {
60
- iss?: string
61
- sub?: string
62
- aud?: string[] | string
63
- exp?: number
64
- nbf?: number
65
- iat?: number
66
- jti?: string
178
+ iss?: string
179
+ sub?: string
180
+ aud?: string[] | string
181
+ exp?: number
182
+ nbf?: number
183
+ iat?: number
184
+ jti?: string
67
185
  }
68
186
 
69
- export interface JwtHeader extends BaseJwtHeader {
70
- kid?: string
71
- jwk?: JWK
72
- x5c?: string[]
187
+ export interface JwsHeader extends BaseJwtHeader {
188
+ kid?: string
189
+ jwk?: JWK
190
+ x5c?: string[]
73
191
 
74
- [key: string]: unknown
192
+ [key: string]: unknown
75
193
  }
76
194
 
77
- export interface JwtPayload extends BaseJwtPayload {
78
- [key: string]: unknown
195
+ export interface JwsPayload extends BaseJwtPayload {
196
+ [key: string]: unknown
79
197
  }
80
198
 
81
199
  export interface JwsHeaderOpts {
82
- als: SignatureAlgorithmJwa
200
+ alg: JoseSignatureAlgorithm | JoseSignatureAlgorithmString
83
201
  }
84
202
 
85
- export type CreateJwsMode = 'x5c' | 'kid' | 'jwk' | 'did' | 'auto'
203
+ export type JwsIdentifierMode = 'x5c' | 'kid' | 'jwk' | 'did' | 'auto'
204
+
205
+ export type EncryptJweCompactJwtArgs = {
206
+ payload: JwsPayload,
207
+ protectedHeader?: JweProtectedHeader | undefined,
208
+ aad?: Uint8Array | undefined
209
+ recipientKey: ExternalIdentifierResult & { kid?: string}
210
+ alg?: JweAlg
211
+ enc?: JweEnc
212
+ apu?: string // base64url
213
+ apv?: string // base64url
214
+ expirationTime?: number | string | Date
215
+ issuer?: string
216
+ audience?: string | string[]
217
+ }
218
+
219
+ export type DecryptJweCompactJwtArgs = {
220
+ jwe: JweCompact
221
+ idOpts: ManagedIdentifierOptsOrResult
222
+ }
86
223
 
87
224
  export type CreateJwsArgs = {
88
- mode?: CreateJwsMode
89
- issuer: ManagedIdentifierOptsOrResult & { noIssPayloadUpdate?: boolean; noIdentifierInHeader?: boolean }
90
- protectedHeader: JwtHeader
91
- payload: JwtPayload | Uint8Array | string
225
+ mode?: JwsIdentifierMode
226
+ issuer: ManagedIdentifierOptsOrResult & {
227
+ noIssPayloadUpdate?: boolean
228
+ noIdentifierInHeader?: boolean
229
+ }
230
+ clientId?: string
231
+ clientIdScheme?: ClientIdScheme | 'did' | string
232
+ protectedHeader: JwsHeader
233
+ payload: JwsPayload | Uint8Array | string
92
234
  }
93
235
 
236
+
237
+ export type CreateJweArgs = {
238
+ mode?: JwsIdentifierMode
239
+ issuer: ManagedIdentifierOptsOrResult & {
240
+ noIssPayloadUpdate?: boolean
241
+ noIdentifierInHeader?: boolean
242
+ }
243
+ protectedHeader: JweProtectedHeader
244
+ encryptedKey: string | EphemeralPublicKey // In case it is a string it is already encrypted; otherwise encrypt //TODO ??
245
+ iv: string
246
+ ciphertext: string
247
+ tag: string
248
+ }
94
249
  export type CreateJwsCompactArgs = CreateJwsArgs
95
250
 
96
251
  export type CreateJwsFlattenedArgs = Exclude<CreateJwsJsonArgs, 'existingSignatures'>
97
252
 
253
+
254
+
255
+
256
+ export type VerifyJwsArgs = {
257
+ jws: Jws
258
+ jwk?: JWK // Jwk will be resolved from jws, but you can also provide one
259
+ opts?: { x5c?: Omit<ExternalIdentifierX5cOpts, 'identifier'>; did?: Omit<ExternalIdentifierDidOpts, 'identifier'> }
260
+ }
261
+
98
262
  /**
99
263
  * @public
100
264
  */
101
265
  export type CreateJwsJsonArgs = CreateJwsArgs & {
102
- unprotectedHeader?: JwtHeader // only for jws json
103
- existingSignatures?: Array<JwsJsonSignature> // Only for jws json
266
+ unprotectedHeader?: JwsHeader // only for jws json
267
+ existingSignatures?: Array<JwsJsonSignature> // Only for jws json
268
+ }
269
+
270
+ export type CreateJweJsonArgs = CreateJweArgs & {
271
+ unprotectedHeader?: JweHeader
104
272
  }
105
273
 
106
274
  /**
107
275
  * @public
108
276
  */
109
- export interface JwsCompactResult {
110
- jwt: JwsCompact
277
+ export interface JwtCompactResult {
278
+ jwt: JwsCompact | JweCompact
279
+ }
280
+
281
+ export function isJwsCompact(jws: Jws): jws is JwsCompact {
282
+ return typeof jws === 'string' && jws.split('~')[0].match(COMPACT_JWS_REGEX) !== null
283
+ }
284
+
285
+ export function isJweCompact(jwe: Jwe): jwe is JweCompact {
286
+ return typeof jwe === 'string' && jwe.split('~')[0].match(COMPACT_JWE_REGEX) !== null
287
+ }
288
+
289
+
290
+ export function isJwsJsonFlattened(jws: Jws): jws is JwsJsonFlattened {
291
+ return typeof jws === 'object' && 'signature' in jws && 'protected' in jws && !('ciphertext' in jws)
292
+ }
293
+
294
+ export function isJwsJsonGeneral(jws: Jws): jws is JwsJsonGeneral {
295
+ return typeof jws === 'object' && 'signatures' in jws && !('ciphertext' in jws)
296
+ }
297
+
298
+
299
+ export function isJweJsonFlattened(jwe: Jwe): jwe is JweJsonFlattened {
300
+ return typeof jwe === 'object' && 'signature' in jwe && 'ciphertext' in jwe && !('payload' in jwe)
301
+ }
302
+
303
+ export function isJweJsonGeneral(jwe: Jwe): jwe is JweJsonGeneral {
304
+ return typeof jwe === 'object' && 'signatures' in jwe && 'ciphertext' in jwe && !('payload' in jwe)
305
+ }
306
+
307
+
308
+ export function isJwsHeader(header: BaseJwtHeader & Record<string, any>): header is JwsHeader {
309
+ return header && !isJweHeader(header)
310
+ }
311
+
312
+ export function isJweHeader(header: BaseJwtHeader & Record<string, any>): header is JweHeader {
313
+ return ('enc' in header && header.enc && jweEnc(header.enc)) || (header.alg && jweAlg(header.alg))
314
+ }
315
+
316
+ export const COMPACT_JWS_REGEX = /^([a-zA-Z0-9_=-]+).([a-zA-Z0-9_=-]+)?.([a-zA-Z0-9_=-]+)?$/
317
+ export const COMPACT_JWE_REGEX = /^([a-zA-Z0-9_=-]+)\.([a-zA-Z0-9_=-]+)?\.([a-zA-Z0-9_=-]+)\.([a-zA-Z0-9_=-]+)?\.([a-zA-Z0-9_=-]+)?$/
318
+
319
+ export const JweAlgs = ['RSA1_5', 'RSA-OAEP', 'RSA-OAEP-256', 'A128KW', 'A192KW', 'A256KW', 'dir', 'ECDH-ES'/*interop value*/, 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW', 'A128GCMKW', 'A192GCMKW', 'A256GCMKW', 'PBES2-HS256+A128KW', 'PBES2-HS384+A192KW', 'PBES2-HS512+A256KW'] as const;
320
+ export type JweAlg = typeof JweAlgs[number]
321
+ export function jweAlg(alg?: string | JweAlg): JweAlg | undefined {
322
+ return JweAlgs.find((supportedVal) => supportedVal === alg);
323
+ }
324
+
325
+
326
+ export const JweEncs = ['A128CBC-HS256', 'A192CBC-HS384', 'A256CBC-HS512', 'A128GCM', 'A192GCM', 'A256GCM'/*interop value*/] as const
327
+ export type JweEnc = typeof JweEncs[number]
328
+
329
+ export function jweEnc(alg?: string | JweEnc): JweEnc | undefined {
330
+ return JweEncs.find((supportedVal) => supportedVal === alg);
111
331
  }
112
332
 
113
- // export const COMPACT_JWS_REGEX = /^([a-zA-Z0-9_=-]+)\.([a-zA-Z0-9_=-]+)?\.([a-zA-Z0-9_=-]+)$/