4
4
import com .auth0 .jwt .exceptions .SignatureGenerationException ;
5
5
import com .auth0 .jwt .exceptions .SignatureVerificationException ;
6
6
import com .auth0 .jwt .interfaces .ECDSAKeyProvider ;
7
+ import com .auth0 .jwt .interfaces .JWTVerifier ;
7
8
import org .hamcrest .Matchers ;
8
9
import org .hamcrest .collection .IsIn ;
9
10
import org .junit .Assert ;
12
13
import org .junit .rules .ExpectedException ;
13
14
14
15
import java .io .ByteArrayOutputStream ;
16
+ import java .math .BigInteger ;
15
17
import java .nio .charset .StandardCharsets ;
16
18
import java .security .*;
17
19
import java .security .interfaces .ECKey ;
18
20
import java .security .interfaces .ECPrivateKey ;
19
21
import java .security .interfaces .ECPublicKey ;
22
+ import java .security .spec .ECParameterSpec ;
20
23
import java .util .Arrays ;
21
24
import java .util .Base64 ;
22
25
@@ -574,6 +577,10 @@ public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exce
574
577
.thenThrow (NoSuchAlgorithmException .class );
575
578
576
579
ECPublicKey publicKey = mock (ECPublicKey .class );
580
+ when (publicKey .getParams ()).thenReturn (mock (ECParameterSpec .class ));
581
+ byte [] a = new byte [64 ];
582
+ Arrays .fill (a , Byte .MAX_VALUE );
583
+ when (publicKey .getParams ().getOrder ()).thenReturn (new BigInteger (a ));
577
584
ECPrivateKey privateKey = mock (ECPrivateKey .class );
578
585
ECDSAKeyProvider provider = ECDSAAlgorithm .providerForKeys (publicKey , privateKey );
579
586
Algorithm algorithm = new ECDSAAlgorithm (crypto , "some-alg" , "some-algorithm" , 32 , provider );
@@ -592,6 +599,10 @@ public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception {
592
599
.thenThrow (InvalidKeyException .class );
593
600
594
601
ECPublicKey publicKey = mock (ECPublicKey .class );
602
+ when (publicKey .getParams ()).thenReturn (mock (ECParameterSpec .class ));
603
+ byte [] a = new byte [64 ];
604
+ Arrays .fill (a , Byte .MAX_VALUE );
605
+ when (publicKey .getParams ().getOrder ()).thenReturn (new BigInteger (a ));
595
606
ECPrivateKey privateKey = mock (ECPrivateKey .class );
596
607
ECDSAKeyProvider provider = ECDSAAlgorithm .providerForKeys (publicKey , privateKey );
597
608
Algorithm algorithm = new ECDSAAlgorithm (crypto , "some-alg" , "some-algorithm" , 32 , provider );
@@ -610,6 +621,10 @@ public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception
610
621
.thenThrow (SignatureException .class );
611
622
612
623
ECPublicKey publicKey = mock (ECPublicKey .class );
624
+ when (publicKey .getParams ()).thenReturn (mock (ECParameterSpec .class ));
625
+ byte [] a = new byte [64 ];
626
+ Arrays .fill (a , Byte .MAX_VALUE );
627
+ when (publicKey .getParams ().getOrder ()).thenReturn (new BigInteger (a ));
613
628
ECPrivateKey privateKey = mock (ECPrivateKey .class );
614
629
ECDSAKeyProvider provider = ECDSAAlgorithm .providerForKeys (publicKey , privateKey );
615
630
Algorithm algorithm = new ECDSAAlgorithm (crypto , "some-alg" , "some-algorithm" , 32 , provider );
@@ -939,12 +954,13 @@ public void shouldThrowOnDERSignatureConversionIfSNumberDoesNotHaveExpectedLengt
939
954
940
955
@ Test
941
956
public void shouldThrowOnJOSESignatureConversionIfDoesNotHaveExpectedLength () throws Exception {
942
- ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 ((ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" ), (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" ));
957
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
958
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" ));
943
959
byte [] joseSignature = new byte [32 * 2 - 1 ];
944
960
exception .expect (SignatureException .class );
945
961
exception .expectMessage ("Invalid JOSE signature format." );
946
962
947
- algorithm256 .JOSEToDER (joseSignature );
963
+ algorithm256 .validateSignatureStructure (joseSignature , publicKey );
948
964
}
949
965
950
966
@ Test
@@ -1309,4 +1325,123 @@ public void shouldFailOnECDSA256SigningWithDeprecatedMethodWhenProvidedPrivateKe
1309
1325
algorithm .sign (new byte [0 ]);
1310
1326
}
1311
1327
1328
+ @ Test
1329
+ public void invalidECDSA256SignatureShouldFailTokenVerification () throws Exception {
1330
+ exception .expect (SignatureVerificationException .class );
1331
+ exception .expectCause (isA (SignatureException .class ));
1332
+
1333
+ String jwtWithInvalidSig = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0._____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" ;
1334
+
1335
+ ECKey key256 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1336
+ ECKey key384 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_384 , "EC" );
1337
+ ECKey key512 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_512 , "EC" );
1338
+ ECKey key256k = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256K , "EC" );
1339
+ JWTVerifier verifier256 = JWT .require (Algorithm .ECDSA256 (key256 )).build ();
1340
+ JWTVerifier verifier384 = JWT .require (Algorithm .ECDSA256 (key384 )).build ();
1341
+ JWTVerifier verifier512 = JWT .require (Algorithm .ECDSA256 (key512 )).build ();
1342
+ JWTVerifier verifier256k = JWT .require (Algorithm .ECDSA256 (key256k )).build ();
1343
+ verifier256 .verify (jwtWithInvalidSig );
1344
+ verifier384 .verify (jwtWithInvalidSig );
1345
+ verifier512 .verify (jwtWithInvalidSig );
1346
+ verifier256k .verify (jwtWithInvalidSig );
1347
+ }
1348
+
1349
+ @ Test
1350
+ public void emptyECDSA256SignatureShouldFailTokenVerification () throws Exception {
1351
+ exception .expect (SignatureVerificationException .class );
1352
+ exception .expectCause (isA (SignatureException .class ));
1353
+
1354
+ String jwtWithInvalidSig = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ;
1355
+
1356
+ ECKey key256 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1357
+ ECKey key384 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_384 , "EC" );
1358
+ ECKey key512 = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_512 , "EC" );
1359
+ ECKey key256k = (ECKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256K , "EC" );
1360
+ JWTVerifier verifier256 = JWT .require (Algorithm .ECDSA256 (key256 )).build ();
1361
+ JWTVerifier verifier384 = JWT .require (Algorithm .ECDSA256 (key384 )).build ();
1362
+ JWTVerifier verifier512 = JWT .require (Algorithm .ECDSA256 (key512 )).build ();
1363
+ JWTVerifier verifier256k = JWT .require (Algorithm .ECDSA256 (key256k )).build ();
1364
+ verifier256 .verify (jwtWithInvalidSig );
1365
+ verifier384 .verify (jwtWithInvalidSig );
1366
+ verifier512 .verify (jwtWithInvalidSig );
1367
+ verifier256k .verify (jwtWithInvalidSig );
1368
+ }
1369
+
1370
+ @ Test
1371
+ public void signatureWithAllZerosShouldFail () throws Exception {
1372
+ exception .expect (SignatureException .class );
1373
+
1374
+ ECPublicKey pubKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1375
+
1376
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (pubKey , (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" ));
1377
+ byte [] signatureBytes = new byte [64 ];
1378
+ algorithm256 .validateSignatureStructure (signatureBytes , pubKey );
1379
+ }
1380
+
1381
+ @ Test
1382
+ public void signatureWithRZeroShouldFail () throws Exception {
1383
+ exception .expect (SignatureException .class );
1384
+
1385
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1386
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1387
+
1388
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1389
+
1390
+ String [] chunks = signedJwt .split ("\\ ." );
1391
+ byte [] signature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1392
+
1393
+ byte [] sigWithBlankR = new byte [signature .length ];
1394
+ for (int i = 0 ; i < signature .length ; i ++) {
1395
+ if (i < signature .length / 2 ) {
1396
+ sigWithBlankR [i ] = 0 ;
1397
+ } else {
1398
+ sigWithBlankR [i ] = signature [i ];
1399
+ }
1400
+ }
1401
+
1402
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1403
+ algorithm256 .validateSignatureStructure (sigWithBlankR , publicKey );
1404
+ }
1405
+
1406
+ @ Test
1407
+ public void signatureWithSZeroShouldFail () throws Exception {
1408
+ exception .expect (SignatureException .class );
1409
+
1410
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1411
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1412
+
1413
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1414
+
1415
+ String [] chunks = signedJwt .split ("\\ ." );
1416
+ byte [] signature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1417
+
1418
+ byte [] sigWithBlankS = new byte [signature .length ];
1419
+ for (int i = 0 ; i < signature .length ; i ++) {
1420
+ if (i < signature .length / 2 ) {
1421
+ sigWithBlankS [i ] = signature [i ];
1422
+ } else {
1423
+ sigWithBlankS [i ] = 0 ;
1424
+ }
1425
+ }
1426
+
1427
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1428
+ algorithm256 .validateSignatureStructure (sigWithBlankS , publicKey );
1429
+ }
1430
+
1431
+ @ Test
1432
+ public void signatureWithRSValueNotLessThanOrderShouldFail () throws Exception {
1433
+ exception .expect (SignatureException .class );
1434
+
1435
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1436
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1437
+
1438
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1439
+ String jwtWithInvalidSig = signedJwt .substring (0 , signedJwt .lastIndexOf ('.' ) + 1 ) + "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" ;
1440
+
1441
+ String [] chunks = jwtWithInvalidSig .split ("\\ ." );
1442
+ byte [] invalidSignature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1443
+
1444
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1445
+ algorithm256 .validateSignatureStructure (invalidSignature , publicKey );
1446
+ }
1312
1447
}
0 commit comments