diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 93aaf05c5..f37f11d87 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -16,6 +16,7 @@ import org.spongycastle.bcpg.SecretSubkeyPacket; import org.spongycastle.bcpg.SignaturePacket; import org.spongycastle.bcpg.UserIDPacket; import org.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; @@ -31,6 +32,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -51,6 +53,8 @@ public class PgpKeyOperationTest { ArrayList onlyB = new ArrayList(); @BeforeClass public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); + ShadowLog.stream = System.out; { @@ -409,6 +413,24 @@ public class PgpKeyOperationTest { expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000); } + { // expiry of 0 should be "no expiry" + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertEquals("old packet must be signature", + PacketTags.SIGNATURE, onlyA.get(0).tag); + + Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); + Assert.assertTrue("first new packet must be signature", p instanceof SignaturePacket); + Assert.assertEquals("signature type must be subkey binding certificate", + PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); + Assert.assertEquals("signature must have been created by master key", + ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); + + Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getExpiryTime()); + } + { // a past expiry should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index bb692555e..fe84b3802 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -543,7 +543,8 @@ public class PgpKeyOperation { PGPPublicKey pKey = sKey.getPublicKey(); // expiry must not be in the past - if (change.mExpiry != null && new Date(change.mExpiry*1000).before(new Date())) { + if (change.mExpiry != null && change.mExpiry != 0 && + new Date(change.mExpiry*1000).before(new Date())) { log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_PAST_EXPIRY, indent + 1, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);