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,146 @@ 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
+ exception .expectMessage ("Invalid signature format." );
1374
+
1375
+ ECPublicKey pubKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1376
+
1377
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (pubKey , (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" ));
1378
+ byte [] signatureBytes = new byte [64 ];
1379
+ algorithm256 .validateSignatureStructure (signatureBytes , pubKey );
1380
+ }
1381
+
1382
+ @ Test
1383
+ public void signatureWithRZeroShouldFail () throws Exception {
1384
+ exception .expect (SignatureException .class );
1385
+ exception .expectMessage ("Invalid signature format." );
1386
+
1387
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1388
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1389
+
1390
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1391
+
1392
+ String [] chunks = signedJwt .split ("\\ ." );
1393
+ byte [] signature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1394
+
1395
+ byte [] sigWithBlankR = new byte [signature .length ];
1396
+ for (int i = 0 ; i < signature .length ; i ++) {
1397
+ if (i < signature .length / 2 ) {
1398
+ sigWithBlankR [i ] = 0 ;
1399
+ } else {
1400
+ sigWithBlankR [i ] = signature [i ];
1401
+ }
1402
+ }
1403
+
1404
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1405
+ algorithm256 .validateSignatureStructure (sigWithBlankR , publicKey );
1406
+ }
1407
+
1408
+ @ Test
1409
+ public void signatureWithSZeroShouldFail () throws Exception {
1410
+ exception .expect (SignatureException .class );
1411
+ exception .expectMessage ("Invalid signature format." );
1412
+
1413
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1414
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1415
+
1416
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1417
+
1418
+ String [] chunks = signedJwt .split ("\\ ." );
1419
+ byte [] signature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1420
+
1421
+ byte [] sigWithBlankS = new byte [signature .length ];
1422
+ for (int i = 0 ; i < signature .length ; i ++) {
1423
+ if (i < signature .length / 2 ) {
1424
+ sigWithBlankS [i ] = signature [i ];
1425
+ } else {
1426
+ sigWithBlankS [i ] = 0 ;
1427
+ }
1428
+ }
1429
+
1430
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1431
+ algorithm256 .validateSignatureStructure (sigWithBlankS , publicKey );
1432
+ }
1433
+
1434
+ @ Test
1435
+ public void signatureWithRValueNotLessThanOrderShouldFail () throws Exception {
1436
+ exception .expect (SignatureException .class );
1437
+ exception .expectMessage ("Invalid signature format." );
1438
+
1439
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1440
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1441
+
1442
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1443
+ String jwtWithInvalidSig = signedJwt .substring (0 , signedJwt .lastIndexOf ('.' ) + 1 ) + "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" ;
1444
+
1445
+ String [] chunks = jwtWithInvalidSig .split ("\\ ." );
1446
+ byte [] invalidSignature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1447
+
1448
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1449
+ algorithm256 .validateSignatureStructure (invalidSignature , publicKey );
1450
+ }
1451
+
1452
+ @ Test
1453
+ public void signatureWithSValueNotLessThanOrderShouldFail () throws Exception {
1454
+ exception .expect (SignatureException .class );
1455
+ exception .expectMessage ("Invalid signature format." );
1456
+
1457
+ ECPublicKey publicKey = (ECPublicKey ) readPublicKeyFromFile (PUBLIC_KEY_FILE_256 , "EC" );
1458
+ ECPrivateKey privateKey = (ECPrivateKey ) readPrivateKeyFromFile (PRIVATE_KEY_FILE_256 , "EC" );
1459
+
1460
+ String signedJwt = JWT .create ().sign (Algorithm .ECDSA256 (publicKey , privateKey ));
1461
+ String jwtWithInvalidSig = signedJwt .substring (0 , signedJwt .lastIndexOf ('.' ) + 1 ) + "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" ;
1462
+
1463
+ String [] chunks = jwtWithInvalidSig .split ("\\ ." );
1464
+ byte [] invalidSignature = Base64 .getUrlDecoder ().decode (chunks [2 ]);
1465
+ invalidSignature [0 ] = Byte .MAX_VALUE ;
1466
+
1467
+ ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm ) Algorithm .ECDSA256 (publicKey , privateKey );
1468
+ algorithm256 .validateSignatureStructure (invalidSignature , publicKey );
1469
+ }
1312
1470
}
0 commit comments