@@ -265,8 +265,8 @@ private static boolean hasContentType(Header header) {
265
265
return header != null && Strings .hasText (header .getContentType ());
266
266
}
267
267
268
- private void verifySignature (final TokenizedJwt tokenized , final JwsHeader jwsHeader , final String alg ,
269
- @ SuppressWarnings ("deprecation" ) SigningKeyResolver resolver , Claims claims , Payload payload ) {
268
+ private byte [] verifySignature (final TokenizedJwt tokenized , final JwsHeader jwsHeader , final String alg ,
269
+ @ SuppressWarnings ("deprecation" ) SigningKeyResolver resolver , Claims claims , Payload payload ) {
270
270
271
271
Assert .notNull (resolver , "SigningKeyResolver instance cannot be null." );
272
272
@@ -354,6 +354,8 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
354
354
} finally {
355
355
Streams .reset (payloadStream );
356
356
}
357
+
358
+ return signature ;
357
359
}
358
360
359
361
@ Override
@@ -485,7 +487,7 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
485
487
}
486
488
487
489
byte [] iv = null ;
488
- byte [] tag = null ;
490
+ byte [] digest = null ; // either JWE AEAD tag or JWS signature after Base64Url-decoding
489
491
if (tokenized instanceof TokenizedJwe ) {
490
492
491
493
TokenizedJwe tokenizedJwe = (TokenizedJwe ) tokenized ;
@@ -521,8 +523,8 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
521
523
base64Url = base64UrlDigest ;
522
524
//guaranteed to be non-empty via the `alg` + digest check above:
523
525
Assert .hasText (base64Url , "JWE AAD Authentication Tag cannot be null or empty." );
524
- tag = decode (base64Url , "JWE AAD Authentication Tag" );
525
- if (Bytes .isEmpty (tag )) {
526
+ digest = decode (base64Url , "JWE AAD Authentication Tag" );
527
+ if (Bytes .isEmpty (digest )) {
526
528
String msg = "Compact JWE strings must always contain an AAD Authentication Tag." ;
527
529
throw new MalformedJwtException (msg );
528
530
}
@@ -564,7 +566,7 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
564
566
// TODO: add encProvider(Provider) builder method that applies to this request only?
565
567
InputStream ciphertext = payload .toInputStream ();
566
568
ByteArrayOutputStream plaintext = new ByteArrayOutputStream (8192 );
567
- DecryptAeadRequest dreq = new DefaultDecryptAeadRequest (ciphertext , cek , aad , iv , tag );
569
+ DecryptAeadRequest dreq = new DefaultDecryptAeadRequest (ciphertext , cek , aad , iv , digest );
568
570
encAlg .decrypt (dreq , plaintext );
569
571
payload = new Payload (plaintext .toByteArray (), header .getContentType ());
570
572
@@ -574,7 +576,7 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
574
576
// not using a signing key resolver, so we can verify the signature before reading the payload, which is
575
577
// always safer:
576
578
JwsHeader jwsHeader = Assert .stateIsInstance (JwsHeader .class , header , "Not a JwsHeader. " );
577
- verifySignature (tokenized , jwsHeader , alg , new LocatingKeyResolver (this .keyLocator ), null , payload );
579
+ digest = verifySignature (tokenized , jwsHeader , alg , new LocatingKeyResolver (this .keyLocator ), null , payload );
578
580
integrityVerified = true ; // no exception means signature verified
579
581
}
580
582
@@ -635,26 +637,28 @@ private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHe
635
637
}
636
638
}
637
639
640
+ // =============== Post-SKR Signature Check =================
641
+ if (hasDigest && signingKeyResolver != null ) { // TODO: remove for 1.0
642
+ // A SigningKeyResolver has been configured, and due to it's API, we have to verify the signature after
643
+ // parsing the body. This can be a security risk, so it needs to be removed before 1.0
644
+ JwsHeader jwsHeader = Assert .stateIsInstance (JwsHeader .class , header , "Not a JwsHeader. " );
645
+ digest = verifySignature (tokenized , jwsHeader , alg , this .signingKeyResolver , claims , payload );
646
+ //noinspection UnusedAssignment
647
+ integrityVerified = true ; // no exception means verified successfully
648
+ }
649
+
638
650
Jwt <?, ?> jwt ;
639
651
Object body = claims != null ? claims : payloadBytes ;
640
652
if (header instanceof JweHeader ) {
641
- jwt = new DefaultJwe <>((JweHeader ) header , body , iv , tag );
653
+ jwt = new DefaultJwe <>((JweHeader ) header , body , iv , digest );
642
654
} else if (hasDigest ) {
643
655
JwsHeader jwsHeader = Assert .isInstanceOf (JwsHeader .class , header , "JwsHeader required." );
644
- jwt = new DefaultJws <>(jwsHeader , body , base64UrlDigest .toString ());
656
+ jwt = new DefaultJws <>(jwsHeader , body , digest , base64UrlDigest .toString ());
645
657
} else {
646
658
//noinspection rawtypes
647
659
jwt = new DefaultJwt (header , body );
648
660
}
649
661
650
- // =============== Signature =================
651
- if (hasDigest && signingKeyResolver != null ) { // TODO: remove for 1.0
652
- // A SigningKeyResolver has been configured, and due to it's API, we have to verify the signature after
653
- // parsing the body. This can be a security risk, so it needs to be removed before 1.0
654
- JwsHeader jwsHeader = Assert .stateIsInstance (JwsHeader .class , header , "Not a JwsHeader. " );
655
- verifySignature (tokenized , jwsHeader , alg , this .signingKeyResolver , claims , payload );
656
- }
657
-
658
662
final boolean allowSkew = this .allowedClockSkewMillis > 0 ;
659
663
660
664
//since 0.3:
0 commit comments