1
1
import type { AgentContext } from '../../agent'
2
- import type { Key , Wallet } from '@credo-ts/core'
2
+ import { X509Certificate , X509ModuleConfig , X509Service , type Key , type Wallet } from '@credo-ts/core'
3
3
4
4
import { InMemoryWallet } from '../../../../../tests/InMemoryWallet'
5
5
import { getAgentConfig , getAgentContext } from '../../../tests/helpers'
@@ -19,6 +19,7 @@ describe('JwsService', () => {
19
19
let agentContext : AgentContext
20
20
let jwsService : JwsService
21
21
let didJwsz6MkfKey : Key
22
+ let didJwsz6MkfCertificate : X509Certificate
22
23
let didJwsz6MkvKey : Key
23
24
let didJwszDnaeyKey : Key
24
25
@@ -27,14 +28,22 @@ describe('JwsService', () => {
27
28
wallet = new InMemoryWallet ( )
28
29
agentContext = getAgentContext ( {
29
30
wallet,
31
+ registerInstances : [ [ X509ModuleConfig , new X509ModuleConfig ( ) ] ] ,
30
32
} )
31
33
await wallet . createAndOpen ( config . walletConfig )
32
34
33
35
jwsService = new JwsService ( )
36
+
34
37
didJwsz6MkfKey = await wallet . createKey ( {
35
38
privateKey : TypedArrayEncoder . fromString ( didJwsz6Mkf . SEED ) ,
36
39
keyType : KeyType . Ed25519 ,
37
40
} )
41
+ didJwsz6MkfCertificate = await X509Service . createCertificate ( agentContext , {
42
+ authorityKey : didJwsz6MkfKey ,
43
+ issuer : {
44
+ countryName : 'NL' ,
45
+ } ,
46
+ } )
38
47
39
48
didJwsz6MkvKey = await wallet . createKey ( {
40
49
privateKey : TypedArrayEncoder . fromString ( didJwsz6Mkv . SEED ) ,
@@ -102,6 +111,80 @@ describe('JwsService', () => {
102
111
)
103
112
} )
104
113
114
+ it ( 'allows both x5c/jwk and kid (no did) to be present' , async ( ) => {
115
+ const payload = JsonEncoder . toBuffer ( didJwsz6Mkf . DATA_JSON )
116
+
117
+ const signed1 = await jwsService . createJwsCompact ( agentContext , {
118
+ payload,
119
+ key : didJwsz6MkfKey ,
120
+ protectedHeaderOptions : {
121
+ alg : JwaSignatureAlgorithm . EdDSA ,
122
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) ,
123
+ kid : 'something' ,
124
+ } ,
125
+ } )
126
+ const { isValid : isValid1 } = await jwsService . verifyJws ( agentContext , {
127
+ jws : signed1 ,
128
+ } )
129
+ expect ( isValid1 ) . toEqual ( true )
130
+
131
+ const signed2 = await jwsService . createJwsCompact ( agentContext , {
132
+ payload,
133
+ key : didJwsz6MkfKey ,
134
+ protectedHeaderOptions : {
135
+ alg : JwaSignatureAlgorithm . EdDSA ,
136
+ x5c : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
137
+ kid : 'something' ,
138
+ } ,
139
+ } )
140
+
141
+ const { isValid : isValid2 } = await jwsService . verifyJws ( agentContext , {
142
+ jws : signed2 ,
143
+ trustedCertificates : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
144
+ } )
145
+ expect ( isValid2 ) . toEqual ( true )
146
+ } )
147
+
148
+ it ( 'throws error whens signing jws with more than one of x5c, jwk, kid (with did)' , async ( ) => {
149
+ const payload = JsonEncoder . toBuffer ( didJwsz6Mkf . DATA_JSON )
150
+
151
+ await expect (
152
+ jwsService . createJwsCompact ( agentContext , {
153
+ payload,
154
+ key : didJwsz6MkfKey ,
155
+ protectedHeaderOptions : {
156
+ alg : JwaSignatureAlgorithm . EdDSA ,
157
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) ,
158
+ kid : 'did:example:123' ,
159
+ } ,
160
+ } )
161
+ ) . rejects . toThrow ( "When 'kid' is a did, 'jwk' and 'x5c' cannot be provided." )
162
+
163
+ await expect (
164
+ jwsService . createJwsCompact ( agentContext , {
165
+ payload,
166
+ key : didJwsz6MkfKey ,
167
+ protectedHeaderOptions : {
168
+ alg : JwaSignatureAlgorithm . EdDSA ,
169
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) ,
170
+ x5c : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
171
+ } ,
172
+ } )
173
+ ) . rejects . toThrow ( "Header must contain one of 'kid' with a did value, 'x5c', or 'jwk'." )
174
+
175
+ await expect (
176
+ jwsService . createJwsCompact ( agentContext , {
177
+ payload,
178
+ key : didJwsz6MkfKey ,
179
+ protectedHeaderOptions : {
180
+ alg : JwaSignatureAlgorithm . EdDSA ,
181
+ kid : 'did:example:123' ,
182
+ x5c : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
183
+ } ,
184
+ } )
185
+ ) . rejects . toThrow ( "When 'kid' is a did, 'jwk' and 'x5c' cannot be provided." )
186
+ } )
187
+
105
188
describe ( 'verifyJws' , ( ) => {
106
189
it ( 'returns true if the jws signature matches the payload' , async ( ) => {
107
190
const { isValid, signerKeys } = await jwsService . verifyJws ( agentContext , {
@@ -149,5 +232,69 @@ describe('JwsService', () => {
149
232
} )
150
233
) . rejects . toThrow ( 'Unable to verify JWS, no signatures present in JWS.' )
151
234
} )
235
+
236
+ it ( 'throws error when verifying jws with more than one of x5c, jwk, kid (with did)' , async ( ) => {
237
+ const payload = JsonEncoder . toBuffer ( didJwsz6Mkf . DATA_JSON )
238
+
239
+ await expect (
240
+ jwsService . verifyJws ( agentContext , {
241
+ jws : {
242
+ header : { } ,
243
+ protected : JsonEncoder . toBase64URL ( {
244
+ alg : JwaSignatureAlgorithm . EdDSA ,
245
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) . toJson ( ) ,
246
+ kid : 'did:example:123' ,
247
+ } ) ,
248
+ payload : '' ,
249
+ signature : '' ,
250
+ } ,
251
+ } )
252
+ ) . rejects . toThrow ( "When 'kid' is a did, 'jwk' and 'x5c' cannot be provided." )
253
+
254
+ await expect (
255
+ jwsService . verifyJws ( agentContext , {
256
+ jws : {
257
+ header : { } ,
258
+ protected : JsonEncoder . toBase64URL ( {
259
+ alg : JwaSignatureAlgorithm . EdDSA ,
260
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) . toJson ( ) ,
261
+ kid : 'did:example:123' ,
262
+ } ) ,
263
+ payload : '' ,
264
+ signature : '' ,
265
+ } ,
266
+ } )
267
+ ) . rejects . toThrow ( "When 'kid' is a did, 'jwk' and 'x5c' cannot be provided." )
268
+
269
+ await expect (
270
+ jwsService . verifyJws ( agentContext , {
271
+ jws : {
272
+ header : { } ,
273
+ protected : JsonEncoder . toBase64URL ( {
274
+ alg : JwaSignatureAlgorithm . EdDSA ,
275
+ jwk : getJwkFromKey ( didJwsz6MkfKey ) . toJson ( ) ,
276
+ x5c : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
277
+ } ) ,
278
+ payload : '' ,
279
+ signature : '' ,
280
+ } ,
281
+ } )
282
+ ) . rejects . toThrow ( "Header must contain one of 'kid' with a did value, 'x5c', or 'jwk'." )
283
+
284
+ await expect (
285
+ jwsService . verifyJws ( agentContext , {
286
+ jws : {
287
+ header : { } ,
288
+ protected : JsonEncoder . toBase64URL ( {
289
+ alg : JwaSignatureAlgorithm . EdDSA ,
290
+ kid : 'did:example:123' ,
291
+ x5c : [ didJwsz6MkfCertificate . toString ( 'base64url' ) ] ,
292
+ } ) ,
293
+ payload : '' ,
294
+ signature : '' ,
295
+ } ,
296
+ } )
297
+ ) . rejects . toThrow ( "When 'kid' is a did, 'jwk' and 'x5c' cannot be provided." )
298
+ } )
152
299
} )
153
300
} )
0 commit comments