mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-26 22:32:07 +01:00
Re-certify expired user-ids when changing key expiration date
This commit is contained in:
parent
710f961984
commit
3aa9e2915a
3 changed files with 39 additions and 12 deletions
|
@ -349,6 +349,38 @@ public class KeyRingInfo {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all user-ids that were valid at some point, but might be expired by now.
|
||||||
|
*
|
||||||
|
* @return bound user-ids
|
||||||
|
*/
|
||||||
|
public List<String> getBoundButPossiblyExpiredUserIds() {
|
||||||
|
List<String> probablyExpired = new ArrayList<>();
|
||||||
|
List<String> userIds = getUserIds();
|
||||||
|
|
||||||
|
for (String userId : userIds) {
|
||||||
|
PGPSignature certification = signatures.userIdCertifications.get(userId);
|
||||||
|
PGPSignature revocation = signatures.userIdRevocations.get(userId);
|
||||||
|
|
||||||
|
// Not revoked -> valid
|
||||||
|
if (revocation == null) {
|
||||||
|
probablyExpired.add(userId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hard revocation -> invalid
|
||||||
|
if (SignatureUtils.isHardRevocation(revocation)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft revocation -> valid if certification is newer than revocation (revalidation)
|
||||||
|
if (certification.getCreationTime().after(revocation.getCreationTime())) {
|
||||||
|
probablyExpired.add(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return probablyExpired;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the provided user-id is valid.
|
* Return true if the provided user-id is valid.
|
||||||
*
|
*
|
||||||
|
@ -371,7 +403,6 @@ public class KeyRingInfo {
|
||||||
PGPSignature certification = signatures.userIdCertifications.get(userId);
|
PGPSignature certification = signatures.userIdCertifications.get(userId);
|
||||||
PGPSignature revocation = signatures.userIdRevocations.get(userId);
|
PGPSignature revocation = signatures.userIdRevocations.get(userId);
|
||||||
|
|
||||||
// If user-id is expired, certification will be null.
|
|
||||||
if (certification == null) {
|
if (certification == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,15 +146,12 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
|
|
||||||
// Determine previous key expiration date
|
// Determine previous key expiration date
|
||||||
PGPPublicKey primaryKey = secretKeyRing.getSecretKey().getPublicKey();
|
PGPPublicKey primaryKey = secretKeyRing.getSecretKey().getPublicKey();
|
||||||
/*
|
|
||||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing);
|
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing);
|
||||||
String primaryUserId = info.getPrimaryUserId();
|
String primaryUserId = info.getPrimaryUserId();
|
||||||
PGPSignature signature = primaryUserId == null ?
|
PGPSignature signature = primaryUserId == null ?
|
||||||
info.getLatestDirectKeySelfSignature() : info.getLatestUserIdCertification(primaryUserId);
|
info.getLatestDirectKeySelfSignature() : info.getLatestUserIdCertification(primaryUserId);
|
||||||
final Date previousKeyExpiration = signature == null ? null :
|
final Date previousKeyExpiration = signature == null ? null :
|
||||||
SignatureSubpacketsUtil.getKeyExpirationTimeAsDate(signature, primaryKey);
|
SignatureSubpacketsUtil.getKeyExpirationTimeAsDate(signature, primaryKey);
|
||||||
*/
|
|
||||||
final Date previousKeyExpiration = null;
|
|
||||||
|
|
||||||
// Add new primary user-id signature
|
// Add new primary user-id signature
|
||||||
addUserId(
|
addUserId(
|
||||||
|
@ -173,8 +170,8 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
protector);
|
protector);
|
||||||
|
|
||||||
// unmark previous primary user-ids to be non-primary
|
// unmark previous primary user-ids to be non-primary
|
||||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing);
|
info = PGPainless.inspectKeyRing(secretKeyRing);
|
||||||
for (String otherUserId : info.getValidUserIds()) {
|
for (String otherUserId : info.getBoundButPossiblyExpiredUserIds()) {
|
||||||
if (userId.toString().equals(otherUserId)) {
|
if (userId.toString().equals(otherUserId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -151,7 +150,7 @@ public class ChangePrimaryUserIdAndExpirationDatesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateA_expire_primaryB_expire_isPrimaryB()
|
public void generateA_expire_primaryB_expire_isPrimaryB()
|
||||||
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, InterruptedException, IOException {
|
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, InterruptedException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("A", null);
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("A", null);
|
||||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ public class ChangePrimaryUserIdAndExpirationDatesTest {
|
||||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
|
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
|
||||||
|
|
||||||
assertIsPrimaryUserId("A", info);
|
assertIsPrimaryUserId("A", info);
|
||||||
assertIsNotValid("A", info);
|
assertIsNotValid("A", info); // A is expired
|
||||||
|
|
||||||
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
||||||
.addPrimaryUserId("B", protector)
|
.addPrimaryUserId("B", protector)
|
||||||
|
@ -174,8 +173,8 @@ public class ChangePrimaryUserIdAndExpirationDatesTest {
|
||||||
info = PGPainless.inspectKeyRing(secretKeys);
|
info = PGPainless.inspectKeyRing(secretKeys);
|
||||||
|
|
||||||
assertIsPrimaryUserId("B", info);
|
assertIsPrimaryUserId("B", info);
|
||||||
assertIsValid("B", info);
|
assertIsNotValid("B", info); // A and B are still expired
|
||||||
assertIsNotValid("A", info); // A is still expired
|
assertIsNotValid("A", info);
|
||||||
|
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ public class ChangePrimaryUserIdAndExpirationDatesTest {
|
||||||
info = PGPainless.inspectKeyRing(secretKeys);
|
info = PGPainless.inspectKeyRing(secretKeys);
|
||||||
|
|
||||||
assertIsValid("B", info);
|
assertIsValid("B", info);
|
||||||
assertIsNotValid("A", info); // A was expired when the expiration date was changed, so it was not re-certified
|
assertIsValid("A", info); // A got re-validated when changing exp date
|
||||||
assertIsPrimaryUserId("B", info);
|
assertIsPrimaryUserId("B", info);
|
||||||
|
|
||||||
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
||||||
|
|
Loading…
Reference in a new issue