Skip to content

Commit 64f7252

Browse files
committed
test sign method in each algorithm
1 parent d13815e commit 64f7252

3 files changed

Lines changed: 386 additions & 32 deletions

File tree

lib/src/test/java/com/auth0/jwt/algorithms/ECDSAAlgorithmTest.java

Lines changed: 150 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
package com.auth0.jwt.algorithms;
22

3+
import com.auth0.jwt.exceptions.SignatureGenerationException;
34
import com.auth0.jwt.exceptions.SignatureVerificationException;
45
import org.apache.commons.codec.binary.Base64;
56
import org.junit.Rule;
67
import org.junit.Test;
78
import org.junit.rules.ExpectedException;
89

9-
import java.io.UnsupportedEncodingException;
1010
import java.security.*;
1111
import java.security.interfaces.ECKey;
12+
import java.security.interfaces.ECPrivateKey;
1213
import java.security.interfaces.ECPublicKey;
1314

1415
import static com.auth0.jwt.PemUtils.readPrivateKeyFromFile;
1516
import static com.auth0.jwt.PemUtils.readPublicKeyFromFile;
16-
import static org.hamcrest.Matchers.is;
17+
import static org.hamcrest.Matchers.*;
1718
import static org.hamcrest.Matchers.isA;
19+
import static org.junit.Assert.assertThat;
1820
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
1921
import static org.mockito.ArgumentMatchers.any;
2022
import static org.mockito.ArgumentMatchers.anyString;
@@ -40,6 +42,8 @@ public class ECDSAAlgorithmTest {
4042
//JOSE Signatures obtained using Node 'jwa' lib: https://github.com/brianloveswords/node-jwa
4143
//DER Signatures obtained from source JOSE signature using 'ecdsa-sig-formatter' lib: https://github.com/Brightspace/node-ecdsa-sig-formatter
4244

45+
// Verify
46+
4347
@Test
4448
public void shouldPassECDSA256VerificationWithJOSESignature() throws Exception {
4549
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g";
@@ -85,7 +89,7 @@ public void shouldFailECDSA256VerificationOnInvalidSignatureLength() throws Exce
8589

8690
byte[] bytes = new byte[63];
8791
new SecureRandom().nextBytes(bytes);
88-
String signature = toBase64(bytes);
92+
String signature = Base64.encodeBase64URLSafeString(bytes);
8993
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
9094
Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC"));
9195
AlgorithmUtils.verify(algorithm, jwt);
@@ -98,7 +102,7 @@ public void shouldFailECDSA256VerificationOnInvalidJOSESignature() throws Except
98102

99103
byte[] bytes = new byte[64];
100104
new SecureRandom().nextBytes(bytes);
101-
String signature = toBase64(bytes);
105+
String signature = Base64.encodeBase64URLSafeString(bytes);
102106
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
103107
Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC"));
104108
AlgorithmUtils.verify(algorithm, jwt);
@@ -112,7 +116,7 @@ public void shouldFailECDSA256VerificationOnInvalidDERSignature() throws Excepti
112116
byte[] bytes = new byte[64];
113117
bytes[0] = 0x30;
114118
new SecureRandom().nextBytes(bytes);
115-
String signature = toBase64(bytes);
119+
String signature = Base64.encodeBase64URLSafeString(bytes);
116120
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
117121
Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC"));
118122
AlgorithmUtils.verify(algorithm, jwt);
@@ -163,7 +167,7 @@ public void shouldFailECDSA384VerificationOnInvalidSignatureLength() throws Exce
163167

164168
byte[] bytes = new byte[95];
165169
new SecureRandom().nextBytes(bytes);
166-
String signature = toBase64(bytes);
170+
String signature = Base64.encodeBase64URLSafeString(bytes);
167171
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
168172
Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC"));
169173
AlgorithmUtils.verify(algorithm, jwt);
@@ -176,7 +180,7 @@ public void shouldFailECDSA384VerificationOnInvalidJOSESignature() throws Except
176180

177181
byte[] bytes = new byte[96];
178182
new SecureRandom().nextBytes(bytes);
179-
String signature = toBase64(bytes);
183+
String signature = Base64.encodeBase64URLSafeString(bytes);
180184
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
181185
Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC"));
182186
AlgorithmUtils.verify(algorithm, jwt);
@@ -190,7 +194,7 @@ public void shouldFailECDSA384VerificationOnInvalidDERSignature() throws Excepti
190194
byte[] bytes = new byte[96];
191195
new SecureRandom().nextBytes(bytes);
192196
bytes[0] = 0x30;
193-
String signature = toBase64(bytes);
197+
String signature = Base64.encodeBase64URLSafeString(bytes);
194198
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
195199
Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC"));
196200
AlgorithmUtils.verify(algorithm, jwt);
@@ -241,7 +245,7 @@ public void shouldFailECDSA512VerificationOnInvalidSignatureLength() throws Exce
241245

242246
byte[] bytes = new byte[131];
243247
new SecureRandom().nextBytes(bytes);
244-
String signature = toBase64(bytes);
248+
String signature = Base64.encodeBase64URLSafeString(bytes);
245249
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
246250
Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC"));
247251
AlgorithmUtils.verify(algorithm, jwt);
@@ -254,7 +258,7 @@ public void shouldFailECDSA512VerificationOnInvalidJOSESignature() throws Except
254258

255259
byte[] bytes = new byte[132];
256260
new SecureRandom().nextBytes(bytes);
257-
String signature = toBase64(bytes);
261+
String signature = Base64.encodeBase64URLSafeString(bytes);
258262
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
259263
Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC"));
260264
AlgorithmUtils.verify(algorithm, jwt);
@@ -268,7 +272,7 @@ public void shouldFailECDSA512VerificationOnInvalidDERSignature() throws Excepti
268272
byte[] bytes = new byte[132];
269273
new SecureRandom().nextBytes(bytes);
270274
bytes[0] = 0x30;
271-
String signature = toBase64(bytes);
275+
String signature = Base64.encodeBase64URLSafeString(bytes);
272276
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
273277
Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC"));
274278
AlgorithmUtils.verify(algorithm, jwt);
@@ -283,15 +287,15 @@ public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws E
283287

284288
byte[] bytes = new byte[256];
285289
new SecureRandom().nextBytes(bytes);
286-
String signature = toBase64(bytes);
290+
String signature = Base64.encodeBase64URLSafeString(bytes);
287291
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
288292

289293
Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"));
290294
AlgorithmUtils.verify(algorithm, jwt);
291295
}
292296

293297
@Test
294-
public void shouldThrowWhenSignatureAlgorithmDoesNotExists() throws Exception {
298+
public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exception {
295299
exception.expect(SignatureVerificationException.class);
296300
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg");
297301
exception.expectCause(isA(NoSuchAlgorithmException.class));
@@ -307,7 +311,7 @@ public void shouldThrowWhenSignatureAlgorithmDoesNotExists() throws Exception {
307311
}
308312

309313
@Test
310-
public void shouldThrowWhenThePublicKeyIsInvalid() throws Exception {
314+
public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception {
311315
exception.expect(SignatureVerificationException.class);
312316
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg");
313317
exception.expectCause(isA(InvalidKeyException.class));
@@ -323,7 +327,7 @@ public void shouldThrowWhenThePublicKeyIsInvalid() throws Exception {
323327
}
324328

325329
@Test
326-
public void shouldThrowWhenTheSignatureIsNotPrepared() throws Exception {
330+
public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception {
327331
exception.expect(SignatureVerificationException.class);
328332
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg");
329333
exception.expectCause(isA(SignatureException.class));
@@ -338,13 +342,136 @@ public void shouldThrowWhenTheSignatureIsNotPrepared() throws Exception {
338342
AlgorithmUtils.verify(algorithm, jwt);
339343
}
340344

341-
private String toBase64(byte[] bytes) {
342-
String res = null;
343-
try {
344-
res = new String(Base64.encodeBase64(bytes, false, true), "UTF-8");
345-
} catch (UnsupportedEncodingException e) {
346-
e.printStackTrace();
347-
}
348-
return res;
345+
//Sign
346+
private static final String ES256Header = "eyJhbGciOiJFUzI1NiJ9";
347+
private static final String ES384Header = "eyJhbGciOiJFUzM4NCJ9";
348+
private static final String ES512Header = "eyJhbGciOiJFUzUxMiJ9";
349+
private static final String auth0IssPayload = "eyJpc3MiOiJhdXRoMCJ9";
350+
351+
@Test
352+
public void shouldDoECDSA256Signing() throws Exception {
353+
Algorithm algorithmSign = Algorithm.ECDSA256((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"));
354+
Algorithm algorithmVerify = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"));
355+
byte[] contentBytes = String.format("%s.%s", ES256Header, auth0IssPayload).getBytes();
356+
byte[] signatureBytes = algorithmSign.sign(contentBytes);
357+
358+
assertThat(signatureBytes, is(notNullValue()));
359+
algorithmVerify.verify(contentBytes, signatureBytes);
360+
}
361+
362+
@Test
363+
public void shouldFailOnECDSA256SigningWhenUsingPublicKey() throws Exception {
364+
exception.expect(SignatureGenerationException.class);
365+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withECDSA");
366+
exception.expectCause(isA(IllegalArgumentException.class));
367+
exception.expectCause(hasMessage(is("The given ECKey is not a ECPrivateKey.")));
368+
369+
Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"));
370+
algorithm.sign(new byte[0]);
371+
}
372+
373+
@Test
374+
public void shouldDoECDSA384Signing() throws Exception {
375+
Algorithm algorithmSign = Algorithm.ECDSA384((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC"));
376+
Algorithm algorithmVerify = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"));
377+
byte[] contentBytes = String.format("%s.%s", ES384Header, auth0IssPayload).getBytes();
378+
byte[] signatureBytes = algorithmSign.sign(contentBytes);
379+
380+
assertThat(signatureBytes, is(notNullValue()));
381+
algorithmVerify.verify(contentBytes, signatureBytes);
382+
}
383+
384+
@Test
385+
public void shouldFailOnECDSA384SigningWhenUsingPublicKey() throws Exception {
386+
exception.expect(SignatureGenerationException.class);
387+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withECDSA");
388+
exception.expectCause(isA(IllegalArgumentException.class));
389+
exception.expectCause(hasMessage(is("The given ECKey is not a ECPrivateKey.")));
390+
391+
Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"));
392+
algorithm.sign(new byte[0]);
393+
}
394+
395+
@Test
396+
public void shouldDoECDSA512Signing() throws Exception {
397+
Algorithm algorithmSign = Algorithm.ECDSA512((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC"));
398+
Algorithm algorithmVerify = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"));
399+
byte[] contentBytes = String.format("%s.%s", ES512Header, auth0IssPayload).getBytes();
400+
byte[] signatureBytes = algorithmSign.sign(contentBytes);
401+
402+
assertThat(signatureBytes, is(notNullValue()));
403+
algorithmVerify.verify(contentBytes, signatureBytes);
404+
}
405+
406+
@Test
407+
public void shouldFailOnECDSA512SigningWhenUsingPublicKey() throws Exception {
408+
exception.expect(SignatureGenerationException.class);
409+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withECDSA");
410+
exception.expectCause(isA(IllegalArgumentException.class));
411+
exception.expectCause(hasMessage(is("The given ECKey is not a ECPrivateKey.")));
412+
413+
Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"));
414+
algorithm.sign(new byte[0]);
415+
}
416+
417+
@Test
418+
public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception {
419+
exception.expect(SignatureGenerationException.class);
420+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm");
421+
exception.expectCause(isA(NoSuchAlgorithmException.class));
422+
423+
CryptoHelper crypto = mock(CryptoHelper.class);
424+
when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class)))
425+
.thenThrow(NoSuchAlgorithmException.class);
426+
427+
ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class));
428+
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, key);
429+
algorithm.sign(ES256Header.getBytes());
430+
}
431+
432+
@Test
433+
public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception {
434+
exception.expect(SignatureGenerationException.class);
435+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm");
436+
exception.expectCause(isA(InvalidKeyException.class));
437+
438+
CryptoHelper crypto = mock(CryptoHelper.class);
439+
when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class)))
440+
.thenThrow(InvalidKeyException.class);
441+
442+
ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class));
443+
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, key);
444+
algorithm.sign(ES256Header.getBytes());
445+
}
446+
447+
@Test
448+
public void shouldThrowOnSignWhenUsingPublicKey() throws Exception {
449+
exception.expect(SignatureGenerationException.class);
450+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm");
451+
exception.expectCause(isA(IllegalArgumentException.class));
452+
exception.expectCause(hasMessage(is("The given ECKey is not a ECPrivateKey.")));
453+
454+
CryptoHelper crypto = mock(CryptoHelper.class);
455+
when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class)))
456+
.thenThrow(InvalidKeyException.class);
457+
458+
ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPublicKey.class));
459+
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, key);
460+
algorithm.sign(ES256Header.getBytes());
461+
}
462+
463+
@Test
464+
public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception {
465+
exception.expect(SignatureGenerationException.class);
466+
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm");
467+
exception.expectCause(isA(SignatureException.class));
468+
469+
CryptoHelper crypto = mock(CryptoHelper.class);
470+
when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class)))
471+
.thenThrow(SignatureException.class);
472+
473+
ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class));
474+
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, key);
475+
algorithm.sign(ES256Header.getBytes());
349476
}
350477
}

0 commit comments

Comments
 (0)