@sphereon/ssi-sdk-ext.jwt-service 0.26.1-next.4 → 0.26.1-next.8
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/agent/JwtService.d.ts.map +1 -1
- package/dist/agent/JwtService.js +6 -4
- package/dist/agent/JwtService.js.map +1 -1
- package/dist/functions/JWE.d.ts +6 -6
- package/dist/functions/JWE.d.ts.map +1 -1
- package/dist/functions/JWE.js +13 -13
- package/dist/functions/JWE.js.map +1 -1
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/IJwtService.d.ts +2 -2
- package/dist/types/IJwtService.d.ts.map +1 -1
- package/dist/types/IJwtService.js +20 -2
- package/dist/types/IJwtService.js.map +1 -1
- package/package.json +10 -10
- package/plugin.schema.json +6 -0
- package/src/agent/JwtService.ts +98 -90
- package/src/functions/JWE.ts +281 -282
- package/src/functions/index.ts +5 -7
- package/src/index.ts +1 -1
- package/src/types/IJwtService.ts +166 -170
package/src/agent/JwtService.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import {IAgentPlugin} from '@veramo/core'
|
|
1
|
+
import { IAgentPlugin } from '@veramo/core'
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
createJwsCompact,
|
|
4
|
+
CreateJwsCompactArgs,
|
|
5
|
+
CreateJwsFlattenedArgs,
|
|
6
|
+
CreateJwsJsonArgs,
|
|
7
|
+
createJwsJsonFlattened,
|
|
8
|
+
createJwsJsonGeneral,
|
|
9
|
+
DecryptJweCompactJwtArgs,
|
|
10
|
+
EncryptJweCompactJwtArgs,
|
|
11
|
+
IJwsValidationResult,
|
|
12
|
+
IJwtService,
|
|
13
|
+
IRequiredContext,
|
|
14
|
+
jweAlg,
|
|
15
|
+
jweEnc,
|
|
16
|
+
JwsJsonFlattened,
|
|
17
|
+
JwsJsonGeneral,
|
|
18
|
+
JwtCompactResult,
|
|
19
|
+
JwtLogger,
|
|
20
|
+
PreparedJwsObject,
|
|
21
|
+
prepareJwsObject,
|
|
22
|
+
schema,
|
|
23
|
+
verifyJws,
|
|
24
|
+
VerifyJwsArgs,
|
|
25
25
|
} from '..'
|
|
26
|
-
import {CompactJwtEncrypter} from
|
|
26
|
+
import { CompactJwtEncrypter } from '../functions/JWE'
|
|
27
27
|
|
|
28
28
|
import * as u8a from 'uint8arrays'
|
|
29
29
|
|
|
@@ -31,81 +31,89 @@ import * as u8a from 'uint8arrays'
|
|
|
31
31
|
* @public
|
|
32
32
|
*/
|
|
33
33
|
export class JwtService implements IAgentPlugin {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
private async jwtPrepareJws(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<PreparedJwsObject> {
|
|
46
|
-
return await prepareJwsObject(args, context)
|
|
47
|
-
}
|
|
34
|
+
readonly schema = schema.IJwtService
|
|
35
|
+
readonly methods: IJwtService = {
|
|
36
|
+
jwtPrepareJws: this.jwtPrepareJws.bind(this),
|
|
37
|
+
jwtCreateJwsJsonGeneralSignature: this.jwtCreateJwsJsonGeneralSignature.bind(this),
|
|
38
|
+
jwtCreateJwsJsonFlattenedSignature: this.jwtCreateJwsJsonFlattenedSignature.bind(this),
|
|
39
|
+
jwtCreateJwsCompactSignature: this.jwtCreateJwsCompactSignature.bind(this),
|
|
40
|
+
jwtVerifyJwsSignature: this.jwtVerifyJwsSignature.bind(this),
|
|
41
|
+
jwtEncryptJweCompactJwt: this.jwtEncryptJweCompactJwt.bind(this),
|
|
42
|
+
jwtDecryptJweCompactJwt: this.jwtDecryptJweCompactJwt.bind(this),
|
|
43
|
+
}
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
private async jwtCreateJwsJsonFlattenedSignature(args: CreateJwsFlattenedArgs, context: IRequiredContext): Promise<JwsJsonFlattened> {
|
|
54
|
-
return await createJwsJsonFlattened(args, context)
|
|
55
|
-
}
|
|
45
|
+
private async jwtPrepareJws(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<PreparedJwsObject> {
|
|
46
|
+
return await prepareJwsObject(args, context)
|
|
47
|
+
}
|
|
56
48
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
49
|
+
private async jwtCreateJwsJsonGeneralSignature(args: CreateJwsJsonArgs, context: IRequiredContext): Promise<JwsJsonGeneral> {
|
|
50
|
+
return await createJwsJsonGeneral(args, context)
|
|
51
|
+
}
|
|
61
52
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
private async jwtCreateJwsJsonFlattenedSignature(args: CreateJwsFlattenedArgs, context: IRequiredContext): Promise<JwsJsonFlattened> {
|
|
54
|
+
return await createJwsJsonFlattened(args, context)
|
|
55
|
+
}
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
private async jwtCreateJwsCompactSignature(args: CreateJwsCompactArgs, context: IRequiredContext): Promise<JwtCompactResult> {
|
|
58
|
+
// We wrap it in a json object for remote REST calls
|
|
59
|
+
return { jwt: await createJwsCompact(args, context) }
|
|
60
|
+
}
|
|
68
61
|
|
|
69
|
-
|
|
62
|
+
private async jwtVerifyJwsSignature(args: VerifyJwsArgs, context: IRequiredContext): Promise<IJwsValidationResult> {
|
|
63
|
+
return await verifyJws(args, context)
|
|
64
|
+
}
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const encJwks = recipientKey.jwks.length === 1 ? [recipientKey.jwks[0]] : recipientKey.jwks.filter(jwk => (jwk.kid && (jwk.kid === jwk.jwk.kid || jwk.kid === jwk.jwkThumbprint)) || jwk.jwk.use === 'enc')
|
|
74
|
-
if (encJwks.length === 0) {
|
|
75
|
-
return Promise.reject(Error(`No public JWK found that can be used to encrypt against`))
|
|
76
|
-
}
|
|
77
|
-
const jwkInfo = encJwks[0]
|
|
78
|
-
if (encJwks.length > 0) {
|
|
79
|
-
JwtLogger.warning(`More than one JWK with 'enc' usage found. Selected the first one as no 'kid' was provided`, encJwks)
|
|
80
|
-
}
|
|
81
|
-
if (jwkInfo.jwk.kty?.startsWith('EC') !== true || !alg.startsWith('ECDH')) {
|
|
82
|
-
return Promise.reject(Error(`Currently only ECDH-ES is supported for encryption. JWK alg ${jwkInfo.jwk.kty}, header alg ${alg}`)) // TODO: Probably we support way more already
|
|
83
|
-
}
|
|
84
|
-
const apuVal = protectedHeader.apu ?? args.apu
|
|
85
|
-
const apu = apuVal ? u8a.fromString(apuVal, 'base64url') : undefined
|
|
86
|
-
const apvVal = protectedHeader.apv ?? args.apv
|
|
87
|
-
const apv = apvVal ? u8a.fromString(apvVal, 'base64url') : undefined
|
|
66
|
+
private async jwtEncryptJweCompactJwt(args: EncryptJweCompactJwtArgs, context: IRequiredContext): Promise<JwtCompactResult> {
|
|
67
|
+
const { payload, protectedHeader = { alg: args.alg, enc: args.enc }, recipientKey, issuer, expirationTime, audience } = args
|
|
88
68
|
|
|
89
|
-
|
|
90
|
-
name: 'ECDH',
|
|
91
|
-
namedCurve: 'P-256',
|
|
92
|
-
}, true, [])
|
|
93
|
-
const encrypter = new CompactJwtEncrypter({
|
|
94
|
-
enc,
|
|
95
|
-
alg,
|
|
96
|
-
keyManagementParams: {apu, apv},
|
|
97
|
-
key: pubKey,
|
|
98
|
-
issuer,
|
|
99
|
-
expirationTime,
|
|
100
|
-
audience
|
|
101
|
-
})
|
|
69
|
+
console.log(JSON.stringify(args, null, 2))
|
|
102
70
|
|
|
103
|
-
|
|
104
|
-
|
|
71
|
+
const alg = jweAlg(args.alg) ?? jweAlg(protectedHeader.alg) ?? 'ECDH-ES'
|
|
72
|
+
const enc = jweEnc(args.enc) ?? jweEnc(protectedHeader.enc) ?? 'A256GCM'
|
|
73
|
+
const encJwks =
|
|
74
|
+
recipientKey.jwks.length === 1
|
|
75
|
+
? [recipientKey.jwks[0]]
|
|
76
|
+
: recipientKey.jwks.filter((jwk) => (jwk.kid && (jwk.kid === jwk.jwk.kid || jwk.kid === jwk.jwkThumbprint)) || jwk.jwk.use === 'enc')
|
|
77
|
+
if (encJwks.length === 0) {
|
|
78
|
+
return Promise.reject(Error(`No public JWK found that can be used to encrypt against`))
|
|
79
|
+
}
|
|
80
|
+
const jwkInfo = encJwks[0]
|
|
81
|
+
if (encJwks.length > 0) {
|
|
82
|
+
JwtLogger.warning(`More than one JWK with 'enc' usage found. Selected the first one as no 'kid' was provided`, encJwks)
|
|
105
83
|
}
|
|
84
|
+
if (jwkInfo.jwk.kty?.startsWith('EC') !== true || !alg.startsWith('ECDH')) {
|
|
85
|
+
return Promise.reject(Error(`Currently only ECDH-ES is supported for encryption. JWK alg ${jwkInfo.jwk.kty}, header alg ${alg}`)) // TODO: Probably we support way more already
|
|
86
|
+
}
|
|
87
|
+
const apuVal = protectedHeader.apu ?? args.apu
|
|
88
|
+
const apu = apuVal ? u8a.fromString(apuVal, 'base64url') : undefined
|
|
89
|
+
const apvVal = protectedHeader.apv ?? args.apv
|
|
90
|
+
const apv = apvVal ? u8a.fromString(apvVal, 'base64url') : undefined
|
|
106
91
|
|
|
107
|
-
|
|
92
|
+
const pubKey = await crypto.subtle.importKey(
|
|
93
|
+
'jwk',
|
|
94
|
+
jwkInfo.jwk,
|
|
95
|
+
{
|
|
96
|
+
name: 'ECDH',
|
|
97
|
+
namedCurve: 'P-256',
|
|
98
|
+
},
|
|
99
|
+
true,
|
|
100
|
+
[]
|
|
101
|
+
)
|
|
102
|
+
const encrypter = new CompactJwtEncrypter({
|
|
103
|
+
enc,
|
|
104
|
+
alg,
|
|
105
|
+
keyManagementParams: { apu, apv },
|
|
106
|
+
key: pubKey,
|
|
107
|
+
issuer,
|
|
108
|
+
expirationTime,
|
|
109
|
+
audience,
|
|
110
|
+
})
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
}
|
|
112
|
+
const jwe = await encrypter.encryptCompactJWT(payload, {})
|
|
113
|
+
return { jwt: jwe }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private async jwtDecryptJweCompactJwt(args: DecryptJweCompactJwtArgs, context: IRequiredContext): Promise<JwtCompactResult> {
|
|
117
|
+
return { jwt: 'FIXME' }
|
|
118
|
+
}
|
|
111
119
|
}
|