mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2024-12-22 12:57:57 +01:00
Initial implementation of 'revoke-key' command
This commit is contained in:
parent
ab2e4aa8e7
commit
e6393b44b9
8 changed files with 151 additions and 0 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
49
sop-java/src/main/java/sop/operation/RevokeKey.java
Normal file
49
sop-java/src/main/java/sop/operation/RevokeKey.java
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue