diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpackets.java b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpackets.java index c622844f..df0269a3 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpackets.java +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpackets.java @@ -212,9 +212,7 @@ public class SignatureSubpackets @Override public SignatureSubpackets setSignatureExpirationTime(boolean isCritical, long seconds) { - if (seconds < 0) { - throw new IllegalArgumentException("Expiration time cannot be negative."); - } + enforceBounds(seconds); return setSignatureExpirationTime(new SignatureExpirationTime(isCritical, seconds)); } @@ -285,12 +283,19 @@ public class SignatureSubpackets @Override public SignatureSubpackets setKeyExpirationTime(boolean isCritical, long secondsFromCreationToExpiration) { - if (secondsFromCreationToExpiration < 0) { - throw new IllegalArgumentException("Seconds from key creation to expiration cannot be less than 0."); - } + enforceBounds(secondsFromCreationToExpiration); return setKeyExpirationTime(new KeyExpirationTime(isCritical, secondsFromCreationToExpiration)); } + private void enforceBounds(long secondsFromCreationToExpiration) { + if (secondsFromCreationToExpiration < 0) { + throw new IllegalArgumentException("Seconds from creation to expiration cannot be less than 0."); + } + if (secondsFromCreationToExpiration > 0xffffffffL) { + throw new IllegalArgumentException("Integer overflow. Seconds from creation to expiration cannot be larger than 0xffffffff"); + } + } + @Override public SignatureSubpackets setKeyExpirationTime(@Nullable KeyExpirationTime keyExpirationTime) { this.keyExpirationTime = keyExpirationTime; diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/modification/ChangeExpirationTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/modification/ChangeExpirationTest.java index 6a1c2f71..7aaf71e4 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/modification/ChangeExpirationTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/modification/ChangeExpirationTest.java @@ -7,6 +7,7 @@ package org.pgpainless.key.modification; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.util.Calendar; @@ -14,13 +15,14 @@ import java.util.Date; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.junit.JUtils; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.JUtils; import org.pgpainless.PGPainless; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.TestKeys; import org.pgpainless.key.info.KeyRingInfo; +import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnprotectedKeysProtector; import org.pgpainless.util.DateUtil; import org.pgpainless.util.TestAllImplementations; @@ -93,4 +95,30 @@ public class ChangeExpirationTest { sInfo = PGPainless.inspectKeyRing(secretKeys); assertNull(sInfo.getPrimaryKeyExpirationDate()); } + + @TestTemplate + @ExtendWith(TestAllImplementations.class) + public void testExtremeExpirationDates() throws PGPException, IOException { + PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing(); + SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); + + // seconds from 2021 to 2199 will overflow 32bit integers + Date farAwayExpiration = DateUtil.parseUTCDate("2199-01-01 00:00:00 UTC"); + + final PGPSecretKeyRing finalKeys = secretKeys; + assertThrows(IllegalArgumentException.class, () -> + PGPainless.modifyKeyRing(finalKeys) + .setExpirationDate(farAwayExpiration, protector) + .done()); + + Date notSoFarAwayExpiration = DateUtil.parseUTCDate("2100-01-01 00:00:00 UTC"); + + secretKeys = PGPainless.modifyKeyRing(secretKeys) + .setExpirationDate(notSoFarAwayExpiration, protector) + .done(); + + Date actualExpiration = PGPainless.inspectKeyRing(secretKeys) + .getPrimaryKeyExpirationDate(); + JUtils.assertDateEquals(notSoFarAwayExpiration, actualExpiration); + } }