Initial implementation of 'revoke-key' command

This commit is contained in:
Paul Schaub 2023-07-11 22:42:16 +02:00
parent ab2e4aa8e7
commit e6393b44b9
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 151 additions and 0 deletions

View file

@ -32,6 +32,7 @@ import sop.operation.InlineDetach;
import sop.operation.InlineSign; import sop.operation.InlineSign;
import sop.operation.InlineVerify; import sop.operation.InlineVerify;
import sop.operation.ListProfiles; import sop.operation.ListProfiles;
import sop.operation.RevokeKey;
import sop.operation.Version; import sop.operation.Version;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -161,6 +162,11 @@ public class ExternalSOP implements SOP {
return new ListProfilesExternal(binaryName, properties); return new ListProfilesExternal(binaryName, properties);
} }
@Override
public RevokeKey revokeKey() {
return null;
}
@Override @Override
public Dearmor dearmor() { public Dearmor dearmor() {
return new DearmorExternal(binaryName, properties); return new DearmorExternal(binaryName, properties);

View file

@ -17,6 +17,7 @@ import sop.cli.picocli.commands.GenerateKeyCmd;
import sop.cli.picocli.commands.InlineSignCmd; import sop.cli.picocli.commands.InlineSignCmd;
import sop.cli.picocli.commands.InlineVerifyCmd; import sop.cli.picocli.commands.InlineVerifyCmd;
import sop.cli.picocli.commands.ListProfilesCmd; import sop.cli.picocli.commands.ListProfilesCmd;
import sop.cli.picocli.commands.RevokeKeyCmd;
import sop.cli.picocli.commands.SignCmd; import sop.cli.picocli.commands.SignCmd;
import sop.cli.picocli.commands.VerifyCmd; import sop.cli.picocli.commands.VerifyCmd;
import sop.cli.picocli.commands.VersionCmd; import sop.cli.picocli.commands.VersionCmd;
@ -43,6 +44,7 @@ import java.util.ResourceBundle;
InlineSignCmd.class, InlineSignCmd.class,
InlineVerifyCmd.class, InlineVerifyCmd.class,
ListProfilesCmd.class, ListProfilesCmd.class,
RevokeKeyCmd.class,
VersionCmd.class, VersionCmd.class,
AutoComplete.GenerateCompletion.class AutoComplete.GenerateCompletion.class
} }

View file

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop.cli.picocli.commands;
import picocli.CommandLine;
import sop.Ready;
import sop.cli.picocli.SopCLI;
import sop.exception.SOPGPException;
import sop.operation.RevokeKey;
import java.io.IOException;
@CommandLine.Command(name = "revoke-key",
resourceBundle = "msg_revoke-key",
exitCodeOnInvalidInput = 37)
public class RevokeKeyCmd extends AbstractSopCmd {
@CommandLine.Option(names = "--no-armor",
negatable = true)
boolean armor = true;
@CommandLine.Option(names = "--with-key-password",
paramLabel = "PASSWORD")
String withKeyPassword;
@Override
public void run() {
RevokeKey revokeKey = throwIfUnsupportedSubcommand(
SopCLI.getSop().revokeKey(), "revoke-key");
if (!armor) {
revokeKey.noArmor();
}
if (withKeyPassword != null) {
try {
String password = stringFromInputStream(getInput(withKeyPassword));
revokeKey.withKeyPassword(password);
} catch (SOPGPException.UnsupportedOption e) {
String errorMsg = getMsg("sop.error.feature_support.option_not_supported", "--with-key-password");
throw new SOPGPException.UnsupportedOption(errorMsg, e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Ready ready;
try {
ready = revokeKey.keys(System.in);
} catch (SOPGPException.KeyIsProtected e) {
String errorMsg = getMsg("sop.error.runtime.cannot_unlock_key", "STANDARD_IN");
throw new SOPGPException.KeyIsProtected(errorMsg, e);
}
try {
ready.writeTo(System.out);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
#
# SPDX-License-Identifier: Apache-2.0
usage.header=Generate revocation certificate for private keys
# Generic TODO: Remove when bumping picocli to 4.7.0
usage.synopsisHeading=Usage:\u0020
usage.commandListHeading = %nCommands:%n
usage.optionListHeading = %nOptions:%n
usage.footerHeading=Powered by picocli%n

View file

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
#
# SPDX-License-Identifier: Apache-2.0
usage.header=Erzeuge Widerrufszertifikate für private Schlüssel
# Generic TODO: Remove when bumping picocli to 4.7.0
usage.synopsisHeading=Aufruf:\u0020
usage.commandListHeading=%nBefehle:%n
usage.optionListHeading = %nOptionen:%n
usage.footerHeading=Powered by Picocli%n

View file

@ -27,6 +27,7 @@ import sop.operation.InlineVerify;
import sop.operation.DetachedSign; import sop.operation.DetachedSign;
import sop.operation.DetachedVerify; import sop.operation.DetachedVerify;
import sop.operation.ListProfiles; import sop.operation.ListProfiles;
import sop.operation.RevokeKey;
import sop.operation.Version; import sop.operation.Version;
public class SOPTest { public class SOPTest {
@ -101,6 +102,11 @@ public class SOPTest {
return null; return null;
} }
@Override
public RevokeKey revokeKey() {
return null;
}
@Override @Override
public InlineDetach inlineDetach() { public InlineDetach inlineDetach() {
return null; return null;

View file

@ -16,6 +16,7 @@ import sop.operation.InlineVerify;
import sop.operation.DetachedSign; import sop.operation.DetachedSign;
import sop.operation.DetachedVerify; import sop.operation.DetachedVerify;
import sop.operation.ListProfiles; import sop.operation.ListProfiles;
import sop.operation.RevokeKey;
import sop.operation.Version; import sop.operation.Version;
/** /**
@ -158,4 +159,11 @@ public interface SOP {
* @return builder instance * @return builder instance
*/ */
ListProfiles listProfiles(); ListProfiles listProfiles();
/**
* Revoke one or more secret keys.
*
* @return builder instance
*/
RevokeKey revokeKey();
} }

View file

@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop.operation;
import sop.Ready;
import sop.exception.SOPGPException;
import sop.util.UTF8Util;
import java.io.InputStream;
public interface RevokeKey {
/**
* Disable ASCII armor encoding.
*
* @return builder instance
*/
RevokeKey noArmor();
/**
* Provide the decryption password for the secret key.
*
* @param password password
* @return builder instance
* @throws SOPGPException.UnsupportedOption if the implementation does not support key passwords
* @throws SOPGPException.PasswordNotHumanReadable if the password is not human-readable
*/
default RevokeKey withKeyPassword(String password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable {
return withKeyPassword(password.getBytes(UTF8Util.UTF8));
}
/**
* Provide the decryption password for the secret key.
*
* @param password password
* @return builder instance
* @throws SOPGPException.UnsupportedOption if the implementation does not support key passwords
* @throws SOPGPException.PasswordNotHumanReadable if the password is not human-readable
*/
RevokeKey withKeyPassword(byte[] password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable;
Ready keys(InputStream keys);
}