Skip to content

Commit b07799a

Browse files
committed
fix: improved key resolution in JsonWebKeyStore
1 parent a0885b1 commit b07799a

2 files changed

Lines changed: 38 additions & 13 deletions

File tree

lib/src/jwk.dart

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -463,24 +463,15 @@ class JsonWebKeyStore {
463463
}
464464

465465
Stream<JsonWebKey> _allKeys(JoseHeader header) async* {
466-
// The key provided by the 'jwk'
467-
if (header.jsonWebKey != null) yield header.jsonWebKey!;
468-
// Other applicable keys available to the application
466+
// The keys added with `addKey`
469467
yield* Stream.fromIterable(_keys);
470468

469+
// The keys added with `addKeySet`
471470
for (var s in _keySets) {
472471
yield* Stream.fromIterable(s.keys);
473472
}
474-
/*
475-
// TODO trust keys from header?
476-
// Keys referenced by the 'jku'
477-
if (header.jwkSetUrl != null) yield* _keysFromSet(header.jwkSetUrl);
478-
// The key referenced by the 'x5u'
479-
// TODO
480-
// The key provided by the 'x5c'
481-
// TODO
482-
*/
483-
// Other applicable keys available to the application
473+
474+
// The keys added with `addKeySetUrl`
484475
for (var url in _keySetUrls) {
485476
yield* _keysFromSet(url).where((v) => v != null).cast();
486477
}

test/jwt_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import 'package:jose/src/jose.dart';
12
import 'package:jose/src/jwk.dart';
23
import 'package:jose/src/jwt.dart';
4+
import 'package:jose/src/jws.dart';
35
import 'package:test/test.dart';
46

57
void main() {
@@ -159,6 +161,38 @@ void main() {
159161
expect(claims.expiry, DateTime.fromMillisecondsSinceEpoch(1300819380000));
160162
});
161163

164+
group('Verification key selection', () {
165+
test('JWT with header jwk is rejected when no matching trusted key exists',
166+
() async {
167+
final trustedKey = JsonWebKey.generate('RS256');
168+
final keyStore = JsonWebKeyStore()..addKey(trustedKey);
169+
170+
final alternateKey = JsonWebKey.generate('RS256');
171+
final claims = JsonWebTokenClaims.fromJson({
172+
'sub': 'user-2',
173+
'iss': 'https://trusted-issuer.example.com',
174+
'aud': 'my-application',
175+
'exp': DateTime.now().add(const Duration(hours: 1)).millisecondsSinceEpoch ~/ 1000,
176+
'iat': DateTime.now().millisecondsSinceEpoch ~/ 1000,
177+
});
178+
final builder = JsonWebSignatureBuilder()
179+
..jsonContent = claims.toJson()
180+
..setProtectedHeader('typ', 'JWT')
181+
..addRecipient(alternateKey, algorithm: 'RS256')
182+
..setProtectedHeader(
183+
'jwk',
184+
JsonWebKey.fromCryptoKeys(
185+
publicKey: alternateKey.cryptoKeyPair.publicKey)
186+
.toJson());
187+
final jwtCompact = builder.build().toCompactSerialization();
188+
189+
expect(
190+
() => JsonWebToken.decodeAndVerify(jwtCompact, keyStore),
191+
throwsA(isA<JoseException>()),
192+
);
193+
});
194+
});
195+
162196
group('JWT with ES256K signature', () {
163197
test('JWT with ES256K signature', () async {
164198
var key = JsonWebKey.fromJson({

0 commit comments

Comments
 (0)