@sphereon/ssi-sdk-ext.jwt-service 0.24.1-unstable.93 → 0.25.1-feature.OIDF.69.39

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,331 @@
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
+ }
131
+
132
+
133
+ export type Jwe = JweCompact | JweJsonFlattened | JweJsonGeneral
134
+ export type JweCompact = string
135
+
136
+ export interface JweJsonFlattened {
137
+ protected: string
138
+ unprotected: JweHeader
139
+ header: JweHeader | JweRecipientUnprotectedHeader
140
+ encrypted_key?: string
141
+ aad?: string
142
+ iv: string
143
+ ciphertext: string
144
+ tag?: string
46
145
  }
47
146
 
147
+
148
+ export interface JweRecipient {
149
+ header?: JweRecipientUnprotectedHeader
150
+ encrypted_key?: string
151
+ }
152
+
153
+ export interface JweJsonGeneral {
154
+ protected: string
155
+ unprotected?: JweHeader
156
+ recipients: Array<JweRecipient>
157
+ aad?: string
158
+ iv: string
159
+ ciphertext: string
160
+ tag?: string
161
+ }
162
+
163
+
48
164
  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
165
+ jws: PreparedJws
166
+ b64: { payload: string; protectedHeader: string } // header is always json, as it can only be used in JwsJson
167
+ identifier: ManagedIdentifierResult
52
168
  }
53
169
 
54
170
  export interface BaseJwtHeader {
55
- typ?: string
56
- alg?: string
57
- kid?: string
171
+ typ?: string
172
+ alg?: string
173
+ kid?: string
58
174
  }
175
+
59
176
  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
177
+ iss?: string
178
+ sub?: string
179
+ aud?: string[] | string
180
+ exp?: number
181
+ nbf?: number
182
+ iat?: number
183
+ jti?: string
67
184
  }
68
185
 
69
- export interface JwtHeader extends BaseJwtHeader {
70
- kid?: string
71
- jwk?: JWK
72
- x5c?: string[]
186
+ export interface JwsHeader extends BaseJwtHeader {
187
+ kid?: string
188
+ jwk?: JWK
189
+ x5c?: string[]
73
190
 
74
- [key: string]: unknown
191
+ [key: string]: unknown
75
192
  }
76
193
 
77
- export interface JwtPayload extends BaseJwtPayload {
78
- [key: string]: unknown
194
+ export interface JwsPayload extends BaseJwtPayload {
195
+ [key: string]: unknown
79
196
  }
80
197
 
81
198
  export interface JwsHeaderOpts {
82
- als: SignatureAlgorithmJwa
199
+ alg: JoseSignatureAlgorithm | JoseSignatureAlgorithmString
83
200
  }
84
201
 
85
- export type CreateJwsMode = 'x5c' | 'kid' | 'jwk' | 'did' | 'auto'
202
+ export type JwsIdentifierMode = 'x5c' | 'kid' | 'jwk' | 'did' | 'auto'
203
+
204
+ export type EncryptJweCompactJwtArgs = {
205
+ payload: JwsPayload,
206
+ protectedHeader?: JweProtectedHeader | undefined,
207
+ aad?: Uint8Array | undefined
208
+ recipientKey: ExternalIdentifierResult & { kid?: string}
209
+ alg?: JweAlg
210
+ enc?: JweEnc
211
+ apu?: string // base64url
212
+ apv?: string // base64url
213
+ expirationTime?: number | string | Date
214
+ issuer?: string
215
+ audience?: string | string[]
216
+ }
217
+
218
+ export type DecryptJweCompactJwtArgs = {
219
+ jwe: JweCompact
220
+ idOpts: ManagedIdentifierOptsOrResult
221
+ }
86
222
 
87
223
  export type CreateJwsArgs = {
88
- mode?: CreateJwsMode
89
- issuer: ManagedIdentifierOptsOrResult & { noIssPayloadUpdate?: boolean; noIdentifierInHeader?: boolean }
90
- protectedHeader: JwtHeader
91
- payload: JwtPayload | Uint8Array | string
224
+ mode?: JwsIdentifierMode
225
+ issuer: ManagedIdentifierOptsOrResult & {
226
+ noIssPayloadUpdate?: boolean
227
+ noIdentifierInHeader?: boolean
228
+ }
229
+ clientId?: string
230
+ clientIdScheme?: ClientIdScheme | 'did' | string
231
+ protectedHeader: JwsHeader
232
+ payload: JwsPayload | Uint8Array | string
92
233
  }
93
234
 
235
+
236
+ export type CreateJweArgs = {
237
+ mode?: JwsIdentifierMode
238
+ issuer: ManagedIdentifierOptsOrResult & {
239
+ noIssPayloadUpdate?: boolean
240
+ noIdentifierInHeader?: boolean
241
+ }
242
+ protectedHeader: JweProtectedHeader
243
+ encryptedKey: string | EphemeralPublicKey // In case it is a string it is already encrypted; otherwise encrypt //TODO ??
244
+ iv: string
245
+ ciphertext: string
246
+ tag: string
247
+ }
94
248
  export type CreateJwsCompactArgs = CreateJwsArgs
95
249
 
96
250
  export type CreateJwsFlattenedArgs = Exclude<CreateJwsJsonArgs, 'existingSignatures'>
97
251
 
252
+
253
+
254
+
255
+ export type VerifyJwsArgs = {
256
+ jws: Jws
257
+ jwk?: JWK // Jwk will be resolved from jws, but you can also provide one
258
+ opts?: { x5c?: Omit<ExternalIdentifierX5cOpts, 'identifier'>; did?: Omit<ExternalIdentifierDidOpts, 'identifier'> }
259
+ }
260
+
98
261
  /**
99
262
  * @public
100
263
  */
101
264
  export type CreateJwsJsonArgs = CreateJwsArgs & {
102
- unprotectedHeader?: JwtHeader // only for jws json
103
- existingSignatures?: Array<JwsJsonSignature> // Only for jws json
265
+ unprotectedHeader?: JwsHeader // only for jws json
266
+ existingSignatures?: Array<JwsJsonSignature> // Only for jws json
267
+ }
268
+
269
+ export type CreateJweJsonArgs = CreateJweArgs & {
270
+ unprotectedHeader?: JweHeader
104
271
  }
105
272
 
106
273
  /**
107
274
  * @public
108
275
  */
109
- export interface JwsCompactResult {
110
- jwt: JwsCompact
276
+ export interface JwtCompactResult {
277
+ jwt: JwsCompact | JweCompact
278
+ }
279
+
280
+ export function isJwsCompact(jws: Jws): jws is JwsCompact {
281
+ return typeof jws === 'string' && jws.split('~')[0].match(COMPACT_JWS_REGEX) !== null
282
+ }
283
+
284
+ export function isJweCompact(jwe: Jwe): jwe is JweCompact {
285
+ return typeof jwe === 'string' && jwe.split('~')[0].match(COMPACT_JWE_REGEX) !== null
286
+ }
287
+
288
+
289
+ export function isJwsJsonFlattened(jws: Jws): jws is JwsJsonFlattened {
290
+ return typeof jws === 'object' && 'signature' in jws && 'protected' in jws && !('ciphertext' in jws)
291
+ }
292
+
293
+ export function isJwsJsonGeneral(jws: Jws): jws is JwsJsonGeneral {
294
+ return typeof jws === 'object' && 'signatures' in jws && !('ciphertext' in jws)
295
+ }
296
+
297
+
298
+ export function isJweJsonFlattened(jwe: Jwe): jwe is JweJsonFlattened {
299
+ return typeof jwe === 'object' && 'signature' in jwe && 'ciphertext' in jwe && !('payload' in jwe)
300
+ }
301
+
302
+ export function isJweJsonGeneral(jwe: Jwe): jwe is JweJsonGeneral {
303
+ return typeof jwe === 'object' && 'signatures' in jwe && 'ciphertext' in jwe && !('payload' in jwe)
304
+ }
305
+
306
+
307
+ export function isJwsHeader(header: BaseJwtHeader & Record<string, any>): header is JwsHeader {
308
+ return header && !isJweHeader(header)
309
+ }
310
+
311
+ export function isJweHeader(header: BaseJwtHeader & Record<string, any>): header is JweHeader {
312
+ return ('enc' in header && header.enc && jweEnc(header.enc)) || (header.alg && jweAlg(header.alg))
313
+ }
314
+
315
+ export const COMPACT_JWS_REGEX = /^([a-zA-Z0-9_=-]+).([a-zA-Z0-9_=-]+)?.([a-zA-Z0-9_=-]+)?$/
316
+ 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_=-]+)?$/
317
+
318
+ 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;
319
+ export type JweAlg = typeof JweAlgs[number]
320
+ export function jweAlg(alg?: string | JweAlg): JweAlg | undefined {
321
+ return JweAlgs.find((supportedVal) => supportedVal === alg);
322
+ }
323
+
324
+
325
+ export const JweEncs = ['A128CBC-HS256', 'A192CBC-HS384', 'A256CBC-HS512', 'A128GCM', 'A192GCM', 'A256GCM'/*interop value*/] as const
326
+ export type JweEnc = typeof JweEncs[number]
327
+
328
+ export function jweEnc(alg?: string | JweEnc): JweEnc | undefined {
329
+ return JweEncs.find((supportedVal) => supportedVal === alg);
111
330
  }
112
331
 
113
- // export const COMPACT_JWS_REGEX = /^([a-zA-Z0-9_=-]+)\.([a-zA-Z0-9_=-]+)?\.([a-zA-Z0-9_=-]+)$/