Skip to content

Commit 07a9ffb

Browse files
committed
[JDKIM-49] Add clock drift tolerance to signature validation
Avoids signature validation failures when clock drift is lower than the threshold.
1 parent b407874 commit 07a9ffb

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

main/src/main/java/org/apache/james/jdkim/DKIMVerifier.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
import java.security.PublicKey;
4848
import java.security.Signature;
4949
import java.security.SignatureException;
50+
import java.time.Duration;
51+
import java.time.Instant;
5052
import java.util.ArrayList;
5153
import java.util.Arrays;
5254
import java.util.HashMap;
@@ -258,26 +260,24 @@ public BodyHasher newBodyHasher(Headers messageHeaders) throws FailException {
258260

259261
// Specification say we MAY refuse to verify the signature.
260262
if (signatureRecord.getSignatureTimestamp() != null) {
261-
long signedTime = signatureRecord.getSignatureTimestamp();
262-
long elapsed = (System.currentTimeMillis() / 1000 - signedTime);
263-
if (elapsed < -3600 * 24 * 365 * 3) {
264-
throw new PermFailException("Signature date is more than "
265-
+ -elapsed / (3600 * 24 * 365) + " years in the future.", signatureRecord);
266-
} else if (elapsed < -3600 * 24 * 30 * 3) {
267-
throw new PermFailException("Signature date is more than "
268-
+ -elapsed / (3600 * 24 * 30) + " months in the future.", signatureRecord);
269-
} else if (elapsed < -3600 * 24 * 3) {
270-
throw new PermFailException("Signature date is more than "
271-
+ -elapsed / (3600 * 24) + " days in the future.", signatureRecord);
272-
} else if (elapsed < -3600 * 3) {
273-
throw new PermFailException("Signature date is more than "
274-
+ -elapsed / 3600 + " hours in the future.", signatureRecord);
275-
} else if (elapsed < -60 * 3) {
276-
throw new PermFailException("Signature date is more than "
277-
+ -elapsed / 60 + " minutes in the future.", signatureRecord);
278-
} else if (elapsed < 0) {
263+
Instant signedTime = Instant.ofEpochSecond(signatureRecord.getSignatureTimestamp());
264+
Instant now = Instant.now();
265+
if (signedTime.isAfter(now.plusSeconds(300))) {
266+
// RFC 6376, Section 3.5 page 25, about clock drift:
267+
// Receivers MAY add a 'fudge factor' to allow for such possible drift.
268+
Duration diff = Duration.between(now, signedTime);
269+
String diffText;
270+
if (diff.toMillis() >= 86400000) {
271+
diffText = diff.toDays() + " day(s)";
272+
} else if (diff.toMillis() >= 3600000) {
273+
diffText = diff.toHours() + " hour(s)";
274+
} else if (diff.toMillis() >= 60000) {
275+
diffText = diff.toMinutes() + " minute(s)";
276+
} else {
277+
diffText = (diff.toMillis() / 1000) + " second(s)";
278+
}
279279
throw new PermFailException("Signature date is "
280-
+ elapsed + " seconds in the future.", signatureRecord);
280+
+ diffText + " in the future.", signatureRecord);
281281
}
282282
}
283283

0 commit comments

Comments
 (0)