Skip to content

Commit 04723bb

Browse files
committed
Update JJWT to version 0.12 and use Jackson ObjectReader, update other dependencies
Note that JJWT 0.12 API is not compatible with 0.11, so this was a non-trivial upgrade. Signed-off-by: Mart Somermaa <[email protected]>
1 parent 1f4f5fa commit 04723bb

File tree

5 files changed

+34
-32
lines changed

5 files changed

+34
-32
lines changed

pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
<properties>
1414
<java.version>11</java.version>
15-
<jjwt.version>0.11.5</jjwt.version>
16-
<bouncycastle.version>1.76</bouncycastle.version>
17-
<jackson.version>2.15.2</jackson.version>
18-
<slf4j.version>2.0.5</slf4j.version>
19-
<junit-jupiter.version>5.9.2</junit-jupiter.version>
20-
<assertj.version>3.24.2</assertj.version>
21-
<mockito.version>5.2.0</mockito.version>
15+
<jjwt.version>0.12.5</jjwt.version>
16+
<bouncycastle.version>1.77</bouncycastle.version>
17+
<jackson.version>2.17.0</jackson.version>
18+
<slf4j.version>2.0.9</slf4j.version>
19+
<junit-jupiter.version>5.10.2</junit-jupiter.version>
20+
<assertj.version>3.25.3</assertj.version>
21+
<mockito.version>5.11.0</mockito.version>
2222
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
2323
<maven-source-plugin.version>3.3.0</maven-source-plugin.version>
2424
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>

src/main/java/eu/webeid/security/validator/AuthTokenSignatureValidator.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
import eu.webeid.security.exceptions.AuthTokenParseException;
2626
import eu.webeid.security.exceptions.AuthTokenSignatureValidationException;
2727
import eu.webeid.security.exceptions.ChallengeNullOrEmptyException;
28-
import io.jsonwebtoken.SignatureAlgorithm;
29-
import io.jsonwebtoken.impl.crypto.DefaultSignatureValidatorFactory;
30-
import io.jsonwebtoken.impl.crypto.SignatureValidator;
31-
import io.jsonwebtoken.security.SignatureException;
28+
import io.jsonwebtoken.Jwts;
29+
import io.jsonwebtoken.impl.security.DefaultVerifySecureDigestRequest;
30+
import io.jsonwebtoken.security.SignatureAlgorithm;
31+
import io.jsonwebtoken.security.VerifySecureDigestRequest;
3232

33+
import java.io.ByteArrayInputStream;
3334
import java.net.URI;
3435
import java.nio.charset.StandardCharsets;
3536
import java.security.MessageDigest;
@@ -73,25 +74,20 @@ public void validate(String algorithm, String signature, PublicKey publicKey, St
7374
throw new AuthTokenParseException("Unsupported signature algorithm");
7475
}
7576

76-
SignatureAlgorithm signatureAlgorithm;
77+
final SignatureAlgorithm signatureAlgorithm = (SignatureAlgorithm) Jwts.SIG.get().forKey(algorithm);
78+
if (signatureAlgorithm == null) {
79+
// Should not happen, see ALLOWED_SIGNATURE_ALGORITHMS check above.
80+
throw new AuthTokenParseException("JJWT does not support signature algorithm: " + algorithm);
81+
}
7782
MessageDigest hashAlgorithm;
7883
try {
79-
signatureAlgorithm = SignatureAlgorithm.forName(algorithm);
8084
hashAlgorithm = hashAlgorithmForName(algorithm);
81-
} catch (SignatureException e) {
82-
// Should not happen, see ALLOWED_SIGNATURE_ALGORITHMS check above.
83-
throw new AuthTokenParseException("Invalid signature algorithm", e);
8485
} catch (NoSuchAlgorithmException e) {
85-
throw new AuthTokenParseException("Invalid hash algorithm", e);
86-
}
87-
if (signatureAlgorithm == null || signatureAlgorithm == SignatureAlgorithm.NONE) {
8886
// Should not happen, see ALLOWED_SIGNATURE_ALGORITHMS check above.
89-
throw new AuthTokenParseException("Invalid signature algorithm");
87+
throw new AuthTokenParseException("Invalid hash algorithm", e);
9088
}
9189
Objects.requireNonNull(hashAlgorithm, "hashAlgorithm");
92-
signatureAlgorithm.assertValidVerificationKey(publicKey);
93-
final SignatureValidator signatureValidator = DefaultSignatureValidatorFactory.INSTANCE
94-
.createSignatureValidator(signatureAlgorithm, publicKey);
90+
9591
final byte[] decodedSignature = decodeBase64(signature);
9692

9793
final byte[] originHash = hashAlgorithm.digest(originBytes);
@@ -100,9 +96,13 @@ public void validate(String algorithm, String signature, PublicKey publicKey, St
10096

10197
// Note that in case of ECDSA, the eID card outputs raw R||S, but JCA's SHA384withECDSA signature
10298
// validation implementation requires the signature in DER encoding.
103-
// JJWT's EllipticCurveProvider.transcodeSignatureToDER() internally takes care of transcoding
104-
// raw R||S to DER as needed inside EllipticCurveProvider.isValid().
105-
if (!signatureValidator.isValid(concatSignedFields, decodedSignature)) {
99+
// JJWT internally takes care of transcoding raw R||S to DER as needed.
100+
final VerifySecureDigestRequest<PublicKey> verificationRequest =
101+
new DefaultVerifySecureDigestRequest<>(
102+
new ByteArrayInputStream(concatSignedFields),
103+
null, null,
104+
publicKey, decodedSignature);
105+
if (!signatureAlgorithm.verify(verificationRequest)) {
106106
throw new AuthTokenSignatureValidationException();
107107
}
108108
}

src/main/java/eu/webeid/security/validator/AuthTokenValidatorImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package eu.webeid.security.validator;
2424

2525
import com.fasterxml.jackson.databind.ObjectMapper;
26+
import com.fasterxml.jackson.databind.ObjectReader;
2627
import eu.webeid.security.authtoken.WebEidAuthToken;
2728
import eu.webeid.security.certificate.CertificateLoader;
2829
import eu.webeid.security.certificate.CertificateValidator;
@@ -57,7 +58,7 @@ final class AuthTokenValidatorImpl implements AuthTokenValidator {
5758
private static final int TOKEN_MAX_LENGTH = 10000;
5859
private static final Logger LOG = LoggerFactory.getLogger(AuthTokenValidatorImpl.class);
5960

60-
private static final ObjectMapper objectMapper = new ObjectMapper();
61+
private static final ObjectReader OBJECT_READER = new ObjectMapper().readerFor(WebEidAuthToken.class);
6162

6263
private final AuthTokenValidationConfiguration configuration;
6364
private final SubjectCertificateValidatorBatch simpleSubjectCertificateValidators;
@@ -138,7 +139,7 @@ private void validateTokenLength(String authToken) throws AuthTokenParseExceptio
138139

139140
private WebEidAuthToken parseToken(String authToken) throws AuthTokenParseException {
140141
try {
141-
final WebEidAuthToken token = objectMapper.readValue(authToken, WebEidAuthToken.class);
142+
final WebEidAuthToken token = OBJECT_READER.readValue(authToken);
142143
if (token == null) {
143144
throw new AuthTokenParseException("Web eID authentication token is null");
144145
}

src/test/java/eu/webeid/security/validator/AuthTokenSignatureValidatorTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package eu.webeid.security.validator;
2424

2525
import com.fasterxml.jackson.databind.ObjectMapper;
26+
import com.fasterxml.jackson.databind.ObjectReader;
2627
import eu.webeid.security.certificate.CertificateLoader;
2728
import org.junit.jupiter.api.Test;
2829
import eu.webeid.security.authtoken.WebEidAuthToken;
@@ -36,9 +37,9 @@
3637

3738
class AuthTokenSignatureValidatorTest {
3839

39-
private static final ObjectMapper objectMapper = new ObjectMapper();
40+
private static final ObjectReader OBJECT_READER = new ObjectMapper().readerFor(WebEidAuthToken.class);
4041

41-
static String VALID_RS256_AUTH_TOKEN = "{\"algorithm\":\"RS256\"," +
42+
private static final String VALID_RS256_AUTH_TOKEN = "{\"algorithm\":\"RS256\"," +
4243
"\"unverifiedCertificate\":\"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\"," +
4344
"\"issuerApp\":\"https://web-eid.eu/web-eid-app/releases/2.0.0+0\"," +
4445
"\"signature\":\"xsjXsQvVYXWcdV0YPhxLthJxtf0//R8p9WFFlYJGRARrl1ruyoAUwl0xeHgeZOKeJtwiCYCNWJzCG3VM3ydgt92bKhhk1u0JXIPVqvOkmDY72OCN4q73Y8iGSPVTgjk93TgquHlodf7YcqZNhutwNNf3oldHEWJD5zmkdwdpBFXgeOwTAdFwGljDQZbHr3h1Dr+apUDuloS0WuIzUuu8YXN2b8lh8FCTlF0G0DEjhHd/MGx8dbe3UTLHmD7K9DXv4zLJs6EF9i2v/C10SIBQDkPBSVPqMxCDPECjbEPi2+ds94eU7ThOhOQlFFtJ4KjQNTUa2crSixH7cYZF2rNNmA==\"," +
@@ -49,7 +50,7 @@ void whenValidES384Signature_thenSucceeds() throws Exception {
4950
final AuthTokenSignatureValidator signatureValidator =
5051
new AuthTokenSignatureValidator(URI.create("https://ria.ee"));
5152

52-
final WebEidAuthToken authToken = objectMapper.readValue(VALID_AUTH_TOKEN, WebEidAuthToken.class);
53+
final WebEidAuthToken authToken = OBJECT_READER.readValue(VALID_AUTH_TOKEN);
5354
final X509Certificate x509Certificate = CertificateLoader.decodeCertificateFromBase64(authToken.getUnverifiedCertificate());
5455

5556
assertThatCode(() -> signatureValidator
@@ -62,7 +63,7 @@ void whenValidRS256Signature_thenSucceeds() throws Exception {
6263
final AuthTokenSignatureValidator signatureValidator =
6364
new AuthTokenSignatureValidator(URI.create("https://ria.ee"));
6465

65-
final WebEidAuthToken authToken = objectMapper.readValue(VALID_RS256_AUTH_TOKEN, WebEidAuthToken.class);
66+
final WebEidAuthToken authToken = OBJECT_READER.readValue(VALID_RS256_AUTH_TOKEN);
6667
final X509Certificate x509Certificate = CertificateLoader.decodeCertificateFromBase64(authToken.getUnverifiedCertificate());
6768

6869
assertThatCode(() -> signatureValidator
2.77 KB
Binary file not shown.

0 commit comments

Comments
 (0)