Skip to content

Commit b6b510a

Browse files
committed
Add tests
1 parent 74d2bae commit b6b510a

4 files changed

Lines changed: 56 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This library is supported for Java LTS versions 8, 11, 17 and 21. For issues on
4545

4646
> Note - Support for ECDSA with curve secp256k1 and SHA-256 (ES256K) has been dropped since it has been [disabled in Java 15](https://www.oracle.com/java/technologies/javase/15-relnote-issues.html#JDK-8237219)
4747
48-
> Note - The RSASSA-PSS algorithms (PS256, PS384, PS512) rely on the JVM for RSASSA-PSS support, which is available natively from Java 11 onwards. On Java 8, a security provider that implements `RSASSA-PSS` (such as [BouncyCastle](https://www.bouncycastle.org/)) must be registered on the classpath; no additional provider is bundled by this library.
48+
> Note - The RSASSA-PSS algorithms (PS256, PS384, PS512) rely on the JVM for RSASSA-PSS support, which is available natively from Java 11 onwards via the `SunRsaSign` provider ([JDK-8146293](https://bugs.openjdk.org/browse/JDK-8146293)). On Java 8, a security provider that implements `RSASSA-PSS` (such as [BouncyCastle](https://www.bouncycastle.org/)) must be registered on the classpath; no additional provider is bundled by this library.
4949
5050
> :warning: **Important security note:** JVM has a critical vulnerability for ECDSA Algorithms - [CVE-2022-21449](https://nvd.nist.gov/vuln/detail/CVE-2022-21449). Please review the details of the vulnerability and update your environment.
5151
### Installation

lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ public static Algorithm RSA512PSS(RSAKey key) throws IllegalArgumentException {
250250
}
251251

252252
private static PSSParameterSpec pssParams(String hashAlgorithm, MGF1ParameterSpec mgf1Spec, int saltLength) {
253+
// JWA (RFC 7518 §3.5) mandates MGF1 with the same hash as the digest and a salt length equal to
254+
// the hash output size (32/48/64 bytes for SHA-256/384/512). Trailer field is the fixed value 1.
253255
return new PSSParameterSpec(hashAlgorithm, "MGF1", mgf1Spec, saltLength, 1);
254256
}
255257

lib/src/main/java/com/auth0/jwt/algorithms/CryptoHelper.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ private static void setParameterIfPresent(Signature s, AlgorithmParameterSpec pa
312312
try {
313313
s.setParameter(params);
314314
} catch (InvalidAlgorithmParameterException e) {
315+
// Remapped to NoSuchAlgorithmException to keep the throws clause unchanged. The params
316+
// are library-controlled (see Algorithm#pssParams), so this branch is effectively
317+
// unreachable; it only fires if a provider rejects the fixed PSS spec entirely.
315318
throw new NoSuchAlgorithmException(
316319
"The algorithm parameters are invalid for the signature algorithm.", e);
317320
}

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.auth0.jwt.exceptions.SignatureVerificationException;
55
import org.bouncycastle.jce.provider.BouncyCastleProvider;
66
import org.junit.AfterClass;
7+
import org.junit.Assume;
78
import org.junit.BeforeClass;
89
import org.junit.Rule;
910
import org.junit.Test;
@@ -128,4 +129,53 @@ public void shouldFailPS256VerificationWithInvalidPublicKey() throws Exception {
128129
Algorithm verifier = Algorithm.RSA256PSS((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA"));
129130
verifier.verify(JWT.decode(jwt));
130131
}
132+
133+
@Test
134+
public void shouldRejectPS256TokenWhenVerifiedWithPS384() throws Exception {
135+
exception.expect(SignatureVerificationException.class);
136+
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: RSASSA-PSS");
137+
138+
Algorithm signer = Algorithm.RSA256PSS((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"));
139+
String jwt = asJWT(signer, PS256Header, auth0IssPayload);
140+
141+
Algorithm verifier = Algorithm.RSA384PSS((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"));
142+
verifier.verify(JWT.decode(jwt));
143+
}
144+
145+
@Test
146+
public void shouldRejectPS256TokenWhenVerifiedWithPS512() throws Exception {
147+
exception.expect(SignatureVerificationException.class);
148+
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: RSASSA-PSS");
149+
150+
Algorithm signer = Algorithm.RSA256PSS((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"));
151+
String jwt = asJWT(signer, PS256Header, auth0IssPayload);
152+
153+
Algorithm verifier = Algorithm.RSA512PSS((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"));
154+
verifier.verify(JWT.decode(jwt));
155+
}
156+
157+
/**
158+
* Exercises the JDK-native RSASSA-PSS implementation (SunRsaSign, Java 11+) rather than the
159+
* BouncyCastle provider the rest of this class relies on. Skipped on Java 8, whose built-in
160+
* providers do not implement RSASSA-PSS.
161+
*/
162+
@Test
163+
public void shouldSignAndVerifyPS256WithJdkNativeProvider() throws Exception {
164+
Assume.assumeFalse("Requires JDK-native RSASSA-PSS (Java 11+)",
165+
System.getProperty("java.specification.version").equals("1.8"));
166+
167+
Security.removeProvider(bcProvider.getName());
168+
try {
169+
Algorithm algorithm = Algorithm.RSA256PSS(
170+
(RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"),
171+
(RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"));
172+
173+
String jwt = asJWT(algorithm, PS256Header, auth0IssPayload);
174+
175+
assertSignaturePresent(jwt);
176+
algorithm.verify(JWT.decode(jwt));
177+
} finally {
178+
Security.insertProviderAt(bcProvider, 1);
179+
}
180+
}
131181
}

0 commit comments

Comments
 (0)