@@ -187,6 +187,23 @@ public String toJson() throws JsonProcessingException, InvalidClaimException {
187187 return jsonMsg ;
188188 }
189189
190+ /**
191+ * Constructs message from JWT. If JWT has no kid defined, allows to try with any otherwise
192+ * matching key in the bundle. Allows extending the keyjar by JKU.
193+ *
194+ * @param jwt
195+ * the jwt String representation of a message
196+ * @param keyJar
197+ * KeyJar having a key for verifying the signature. If null, signature is not verified.
198+ * @param keyOwner
199+ * For whom the key belongs to.
200+ * @throws IOException
201+ * thrown if message parameters do not match the message requirements.
202+ */
203+ public void fromJwt (String jwt , KeyJar keyJar , String keyOwner ) throws IOException {
204+ fromJwt (jwt , keyJar , keyOwner , null , true , true );
205+ }
206+
190207 /**
191208 * Constructs message from JWT.
192209 *
@@ -196,11 +213,20 @@ public String toJson() throws JsonProcessingException, InvalidClaimException {
196213 * KeyJar having a key for verifying the signature. If null, signature is not verified.
197214 * @param keyOwner
198215 * For whom the key belongs to.
216+ * @param noKidIssuers
217+ * If jwt is missing kid, set the list of allowed kids in keyjar to verify jwt. if
218+ * allowMissingKid is set to true, list is not used.
219+ * @param allowMissingKid
220+ * If jwt is missing kid, try any of the owners keys to verify jwt.
221+ * @param trustJKU
222+ * Whether extending keyjar by JKU is allowed or not.
199223 * @throws InvalidClaimException
200224 * thrown if message parameters do not match the message requirements.
201225 */
202226 @ SuppressWarnings ("unchecked" )
203- public void fromJwt (String jwt , KeyJar keyJar , String keyOwner ) throws IOException {
227+ public void fromJwt (String jwt , KeyJar keyJar , String keyOwner ,
228+ Map <String , List <String >> noKidIssuers , boolean allowMissingKid , boolean trustJKU )
229+ throws IOException {
204230 String [] parts = MessageUtil .splitToken (jwt );
205231 String headerJson ;
206232 String payloadJson ;
@@ -230,57 +256,36 @@ public void fromJwt(String jwt, KeyJar keyJar, String keyOwner) throws IOExcepti
230256 verifier .verify (jwt );
231257 return ;
232258 }
233-
234- Map <String , String > args = new HashMap <String , String >();
235- args .put ("alg" , alg );
236- if (header .get ("kid" ) != null && !(header .get ("alg" ) instanceof String )) {
237- throw new JWTDecodeException ("JWT header field kid has to be string" );
238- }
239- // Get matching keys
240- String kid = (String ) header .get ("kid" );
241- List <Key > keys = null ;
242- switch (alg ) {
243- case "RS256" :
244- case "RS384" :
245- case "RS512" :
246- keys = keyJar .getVerifyKey (KeyType .RSA .name (), keyOwner , kid , args );
247- break ;
248- case "ES256" :
249- case "ES384" :
250- case "ES512" :
251- keys = keyJar .getVerifyKey (KeyType .EC .name (), keyOwner , kid , args );
252- break ;
253- default :
254- break ;
255- }
259+ List <java .security .Key > keys = keyJar .getJWTVerifyKeys (jwt , keyOwner , noKidIssuers ,
260+ allowMissingKid , trustJKU );
256261 if (keys == null || keys .size () == 0 ) {
257262 throw new JWTDecodeException ("Not able to locate keys to verify JWT" );
258263 }
259264 // We try each located key
260265 try {
261- for (Key key : keys ) {
266+ for (java . security . Key key : keys ) {
262267 Algorithm algorithm = null ;
263268 switch (alg ) {
264- case "RS256" :
265- algorithm = Algorithm .RSA256 ((RSAPublicKey ) key . getKey ( false ) , null );
266- break ;
267- case "RS384" :
268- algorithm = Algorithm .RSA384 ((RSAPublicKey ) key . getKey ( false ) , null );
269- break ;
270- case "RS512" :
271- algorithm = Algorithm .RSA512 ((RSAPublicKey ) key . getKey ( false ) , null );
272- break ;
273- case "ES256" :
274- algorithm = Algorithm .ECDSA256 ((ECPublicKey ) key . getKey ( false ) , null );
275- break ;
276- case "ES384" :
277- algorithm = Algorithm .ECDSA384 ((ECPublicKey ) key . getKey ( false ) , null );
278- break ;
279- case "ES512" :
280- algorithm = Algorithm .ECDSA512 ((ECPublicKey ) key . getKey ( false ) , null );
281- break ;
282- default :
283- break ;
269+ case "RS256" :
270+ algorithm = Algorithm .RSA256 ((RSAPublicKey ) key , null );
271+ break ;
272+ case "RS384" :
273+ algorithm = Algorithm .RSA384 ((RSAPublicKey ) key , null );
274+ break ;
275+ case "RS512" :
276+ algorithm = Algorithm .RSA512 ((RSAPublicKey ) key , null );
277+ break ;
278+ case "ES256" :
279+ algorithm = Algorithm .ECDSA256 ((ECPublicKey ) key , null );
280+ break ;
281+ case "ES384" :
282+ algorithm = Algorithm .ECDSA384 ((ECPublicKey ) key , null );
283+ break ;
284+ case "ES512" :
285+ algorithm = Algorithm .ECDSA512 ((ECPublicKey ) key , null );
286+ break ;
287+ default :
288+ break ;
284289 }
285290 if (algorithm == null ) {
286291 throw new JWTDecodeException ("Not able to initialize algorithm to verify JWT" );
@@ -294,7 +299,7 @@ public void fromJwt(String jwt, KeyJar keyJar, String keyOwner) throws IOExcepti
294299 continue ;
295300 }
296301 }
297- } catch (IllegalArgumentException | ValueError e ) {
302+ } catch (IllegalArgumentException e ) {
298303 throw new JWTDecodeException ("Key handling exception" );
299304 }
300305 throw new JWTDecodeException ("Not able to verify JWT with any of the keys provided" );
@@ -322,30 +327,30 @@ public String toJwt(Key key, String alg) {
322327 Algorithm algorithm = null ;
323328 try {
324329 switch (alg ) {
325- case "none" :
326- algorithm = Algorithm .none ();
327- break ;
328- case "RS256" :
329- algorithm = Algorithm .RSA256 (null , (RSAPrivateKey ) key .getKey (true ));
330- break ;
331- case "RS384" :
332- algorithm = Algorithm .RSA384 (null , (RSAPrivateKey ) key .getKey (true ));
333- break ;
334- case "RS512" :
335- algorithm = Algorithm .RSA512 (null , (RSAPrivateKey ) key .getKey (true ));
336- break ;
337- case "ES256" :
338- algorithm = Algorithm .ECDSA256 (null , (ECPrivateKey ) key .getKey (true ));
339- break ;
340- case "ES384" :
341- algorithm = Algorithm .ECDSA384 (null , (ECPrivateKey ) key .getKey (true ));
342- break ;
343- case "ES512" :
344- algorithm = Algorithm .ECDSA512 (null , (ECPrivateKey ) key .getKey (true ));
345- break ;
346- default :
347- break ;
348- // TODO: HMAC algorithms
330+ case "none" :
331+ algorithm = Algorithm .none ();
332+ break ;
333+ case "RS256" :
334+ algorithm = Algorithm .RSA256 (null , (RSAPrivateKey ) key .getKey (true ));
335+ break ;
336+ case "RS384" :
337+ algorithm = Algorithm .RSA384 (null , (RSAPrivateKey ) key .getKey (true ));
338+ break ;
339+ case "RS512" :
340+ algorithm = Algorithm .RSA512 (null , (RSAPrivateKey ) key .getKey (true ));
341+ break ;
342+ case "ES256" :
343+ algorithm = Algorithm .ECDSA256 (null , (ECPrivateKey ) key .getKey (true ));
344+ break ;
345+ case "ES384" :
346+ algorithm = Algorithm .ECDSA384 (null , (ECPrivateKey ) key .getKey (true ));
347+ break ;
348+ case "ES512" :
349+ algorithm = Algorithm .ECDSA512 (null , (ECPrivateKey ) key .getKey (true ));
350+ break ;
351+ default :
352+ break ;
353+ // TODO: HMAC algorithms, are getting client secret also from key jar?
349354 }
350355 } catch (IllegalArgumentException | ValueError e ) {
351356 // TODO: This is not Decoding exception, replace it.
0 commit comments