From 8305fcf0ee74b1cea15fb8c145b4448a2579250e Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 20 Nov 2020 12:19:45 +0100 Subject: [PATCH] Allow for revocation attributes to be passed in when revoking subkey directly --- .../secretkeyring/SecretKeyRingEditor.java | 19 ++++-- .../SecretKeyRingEditorInterface.java | 65 ++++++++++++++++++- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java index 78ec5a7b..e5c635fa 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java @@ -258,19 +258,24 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { } @Override - public SecretKeyRingEditorInterface revokeSubKey(OpenPgpV4Fingerprint fingerprint, SecretKeyRingProtector protector) + public SecretKeyRingEditorInterface revokeSubKey(OpenPgpV4Fingerprint fingerprint, + SecretKeyRingProtector protector, + RevocationAttributes revocationAttributes) throws PGPException { - return revokeSubKey(fingerprint.getKeyId(), protector); + return revokeSubKey(fingerprint.getKeyId(), protector, revocationAttributes); } @Override - public SecretKeyRingEditorInterface revokeSubKey(long subKeyId, SecretKeyRingProtector protector) throws PGPException { + public SecretKeyRingEditorInterface revokeSubKey(long subKeyId, + SecretKeyRingProtector protector, + RevocationAttributes revocationAttributes) + throws PGPException { PGPPublicKey revokeeSubKey = secretKeyRing.getPublicKey(subKeyId); if (revokeeSubKey == null) { throw new NoSuchElementException("No subkey with id " + Long.toHexString(subKeyId) + " found."); } - secretKeyRing = revokeSubKey(protector, revokeeSubKey); + secretKeyRing = revokeSubKey(protector, revokeeSubKey, revocationAttributes); return this; } @@ -302,9 +307,11 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { return revocationCertificate; } - private PGPSecretKeyRing revokeSubKey(SecretKeyRingProtector protector, PGPPublicKey revokeeSubKey) + private PGPSecretKeyRing revokeSubKey(SecretKeyRingProtector protector, + PGPPublicKey revokeeSubKey, + RevocationAttributes revocationAttributes) throws PGPException { - PGPSignature subKeyRevocation = generateRevocation(protector, revokeeSubKey, null); + PGPSignature subKeyRevocation = generateRevocation(protector, revokeeSubKey, revocationAttributes); revokeeSubKey = PGPPublicKey.addCertification(revokeeSubKey, subKeyRevocation); // Inject revoked public key into key ring diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java index 80a462c0..f3c91d96 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java @@ -117,7 +117,26 @@ public interface SecretKeyRingEditorInterface { * @param fingerprint fingerprint of the subkey to be revoked * @return the builder */ - SecretKeyRingEditorInterface revokeSubKey(OpenPgpV4Fingerprint fingerprint, SecretKeyRingProtector secretKeyRingProtector) throws PGPException; + default SecretKeyRingEditorInterface revokeSubKey(OpenPgpV4Fingerprint fingerprint, + SecretKeyRingProtector secretKeyRingProtector) + throws PGPException { + return revokeSubKey(fingerprint, secretKeyRingProtector, null); + } + + /** + * Revoke the subkey binding signature of a subkey. + * The subkey with the provided fingerprint will be revoked. + * If no suitable subkey is found, a {@link java.util.NoSuchElementException} will be thrown. + * + * @param fingerprint fingerprint of the subkey to be revoked + * @param secretKeyRingProtector protector to unlock the primary key + * @param revocationAttributes reason for the revocation + * @return the builder + */ + SecretKeyRingEditorInterface revokeSubKey(OpenPgpV4Fingerprint fingerprint, + SecretKeyRingProtector secretKeyRingProtector, + RevocationAttributes revocationAttributes) + throws PGPException; /** * Revoke the subkey binding signature of a subkey. @@ -127,13 +146,48 @@ public interface SecretKeyRingEditorInterface { * @param subKeyId id of the subkey * @return the builder */ - SecretKeyRingEditorInterface revokeSubKey(long subKeyId, SecretKeyRingProtector secretKeyRingProtector) throws PGPException; + default SecretKeyRingEditorInterface revokeSubKey(long subKeyId, + SecretKeyRingProtector secretKeyRingProtector) + throws PGPException { + return revokeSubKey(subKeyId, secretKeyRingProtector, null); + } + /** + * Revoke the subkey binding signature of a subkey. + * The subkey with the provided key-id will be revoked. + * If no suitable subkey is found, q {@link java.util.NoSuchElementException} will be thrown. + * + * @param subKeyId id of the subkey + * @param secretKeyRingProtector protector to unlock the primary key + * @param revocationAttributes reason for the revocation + * @return the builder + */ + SecretKeyRingEditorInterface revokeSubKey(long subKeyId, + SecretKeyRingProtector secretKeyRingProtector, + RevocationAttributes revocationAttributes) + throws PGPException; + + /** + * Create a detached revocation certificate, which can be used to revoke the specified key. + * + * @param fingerprint fingerprint of the key to be revoked. Can be primary or sub key. + * @param secretKeyRingProtector protector to unlock the primary key. + * @param revocationAttributes reason for the revocation + * @return revocation certificate + */ PGPSignature createRevocationCertificate(OpenPgpV4Fingerprint fingerprint, SecretKeyRingProtector secretKeyRingProtector, RevocationAttributes revocationAttributes) throws PGPException; + /** + * Create a detached revocation certificate, which can be used to revoke the specified key. + * + * @param subKeyId id of the key to be revoked. Can be primary or sub key. + * @param secretKeyRingProtector protector to unlock the primary key. + * @param revocationAttributes reason for the revocation + * @return revocation certificate + */ PGPSignature createRevocationCertificate(long subKeyId, SecretKeyRingProtector secretKeyRingProtector, RevocationAttributes revocationAttributes) @@ -149,6 +203,13 @@ public interface SecretKeyRingEditorInterface { return changePassphraseFromOldPassphrase(oldPassphrase, KeyRingProtectionSettings.secureDefaultSettings()); } + /** + * Change the passphrase of the whole key ring. + * + * @param oldPassphrase old passphrase or null, if the key was unprotected + * @param oldProtectionSettings custom settings for the old passphrase + * @return next builder step + */ WithKeyRingEncryptionSettings changePassphraseFromOldPassphrase(@Nullable Passphrase oldPassphrase, @Nonnull KeyRingProtectionSettings oldProtectionSettings);