mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-10 10:49:39 +02:00
Update SOP implementation to the latest spec version
See https://datatracker.ietf.org/doc/html/draft-dkg-openpgp-stateless-cli-03
This commit is contained in:
parent
5e0ca369bf
commit
1cb49f4b12
21 changed files with 348 additions and 112 deletions
55
sop-java/src/main/java/sop/MicAlg.java
Normal file
55
sop-java/src/main/java/sop/MicAlg.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class MicAlg {
|
||||
|
||||
private final String micAlg;
|
||||
|
||||
public MicAlg(String micAlg) {
|
||||
if (micAlg == null) {
|
||||
throw new IllegalArgumentException("MicAlg String cannot be null.");
|
||||
}
|
||||
this.micAlg = micAlg;
|
||||
}
|
||||
|
||||
public static MicAlg empty() {
|
||||
return new MicAlg("");
|
||||
}
|
||||
|
||||
public static MicAlg fromHashAlgorithmId(int id) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return new MicAlg("pgp-md5");
|
||||
case 2:
|
||||
return new MicAlg("pgp-sha1");
|
||||
case 3:
|
||||
return new MicAlg("pgp-ripemd160");
|
||||
case 8:
|
||||
return new MicAlg("pgp-sha256");
|
||||
case 9:
|
||||
return new MicAlg("pgp-sha384");
|
||||
case 10:
|
||||
return new MicAlg("pgp-sha512");
|
||||
case 11:
|
||||
return new MicAlg("pgp-sha224");
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported hash algorithm ID: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public String getMicAlg() {
|
||||
return micAlg;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream outputStream) {
|
||||
PrintWriter pw = new PrintWriter(outputStream);
|
||||
pw.write(getMicAlg());
|
||||
pw.close();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
|
||||
public abstract int getExitCode();
|
||||
|
||||
/**
|
||||
* No acceptable signatures found (sop verify).
|
||||
*/
|
||||
public static class NoSignature extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 3;
|
||||
|
@ -38,6 +41,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asymmetric algorithm unsupported (sop encrypt).
|
||||
*/
|
||||
public static class UnsupportedAsymmetricAlgo extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 13;
|
||||
|
@ -56,6 +62,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Certificate not encryption capable (e,g, expired, revoked, unacceptable usage).
|
||||
*/
|
||||
public static class CertCannotEncrypt extends SOPGPException {
|
||||
public static final int EXIT_CODE = 17;
|
||||
|
||||
|
@ -69,10 +78,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
public static class CertCannotSign extends Exception {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Missing required argument.
|
||||
*/
|
||||
public static class MissingArg extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 19;
|
||||
|
@ -87,6 +95,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Incomplete verification instructions (sop decrypt).
|
||||
*/
|
||||
public static class IncompleteVerification extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 23;
|
||||
|
@ -101,6 +112,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unable to decrypt (sop decrypt).
|
||||
*/
|
||||
public static class CannotDecrypt extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 29;
|
||||
|
@ -111,6 +125,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-UTF-8 or otherwise unreliable password (sop encrypt).
|
||||
*/
|
||||
public static class PasswordNotHumanReadable extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 31;
|
||||
|
@ -121,6 +138,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsupported option.
|
||||
*/
|
||||
public static class UnsupportedOption extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 37;
|
||||
|
@ -139,6 +159,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid data type (no secret key where KEYS expected, etc.).
|
||||
*/
|
||||
public static class BadData extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 41;
|
||||
|
@ -157,6 +180,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-Text input where text expected.
|
||||
*/
|
||||
public static class ExpectedText extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 53;
|
||||
|
@ -167,6 +193,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output file already exists.
|
||||
*/
|
||||
public static class OutputExists extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 59;
|
||||
|
@ -181,6 +210,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input file does not exist.
|
||||
*/
|
||||
public static class MissingInput extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 61;
|
||||
|
@ -195,6 +227,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A KEYS input is protected (locked) with a password, and sop cannot unlock it.
|
||||
*/
|
||||
public static class KeyIsProtected extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 67;
|
||||
|
@ -213,6 +248,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsupported subcommand.
|
||||
*/
|
||||
public static class UnsupportedSubcommand extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 69;
|
||||
|
@ -227,6 +265,9 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An indirect parameter is a special designator (it starts with @), but sop does not know how to handle the prefix.
|
||||
*/
|
||||
public static class UnsupportedSpecialPrefix extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 71;
|
||||
|
@ -237,7 +278,10 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A indirect input parameter is a special designator (it starts with @),
|
||||
* and a filename matching the designator is actually present.
|
||||
*/
|
||||
public static class AmbiguousInput extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 73;
|
||||
|
@ -251,4 +295,30 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
return EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key not signature-capable (e.g. expired, revoked, unacceptable usage flags)
|
||||
* (sop sign and sop encrypt with --sign-with).
|
||||
*/
|
||||
public static class KeyCannotSign extends SOPGPException {
|
||||
|
||||
public static final int EXIT_CODE = 79;
|
||||
|
||||
public KeyCannotSign() {
|
||||
super();
|
||||
}
|
||||
|
||||
public KeyCannotSign(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public KeyCannotSign(String s, KeyCannotSign keyCannotSign) {
|
||||
super(s, keyCannotSign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitCode() {
|
||||
return EXIT_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ public interface Decrypt {
|
|||
throws SOPGPException.UnsupportedOption;
|
||||
|
||||
/**
|
||||
* Adds the verification cert.
|
||||
* Adds one or more verification cert.
|
||||
*
|
||||
* @param cert input stream containing the cert
|
||||
* @param cert input stream containing the cert(s)
|
||||
* @return builder instance
|
||||
*/
|
||||
Decrypt verifyWithCert(InputStream cert)
|
||||
|
@ -45,9 +45,9 @@ public interface Decrypt {
|
|||
IOException;
|
||||
|
||||
/**
|
||||
* Adds the verification cert.
|
||||
* Adds one or more verification cert.
|
||||
*
|
||||
* @param cert byte array containing the cert
|
||||
* @param cert byte array containing the cert(s)
|
||||
* @return builder instance
|
||||
*/
|
||||
default Decrypt verifyWithCert(byte[] cert)
|
||||
|
@ -75,9 +75,9 @@ public interface Decrypt {
|
|||
SOPGPException.UnsupportedOption;
|
||||
|
||||
/**
|
||||
* Adds the decryption key.
|
||||
* Adds one or more decryption key.
|
||||
*
|
||||
* @param key input stream containing the key
|
||||
* @param key input stream containing the key(s)
|
||||
* @return builder instance
|
||||
*/
|
||||
Decrypt withKey(InputStream key)
|
||||
|
@ -86,9 +86,9 @@ public interface Decrypt {
|
|||
SOPGPException.UnsupportedAsymmetricAlgo;
|
||||
|
||||
/**
|
||||
* Adds the decryption key.
|
||||
* Adds one or more decryption key.
|
||||
*
|
||||
* @param key byte array containing the key
|
||||
* @param key byte array containing the key(s)
|
||||
* @return builder instance
|
||||
*/
|
||||
default Decrypt withKey(byte[] key)
|
||||
|
|
|
@ -38,7 +38,7 @@ public interface Encrypt {
|
|||
*/
|
||||
Encrypt signWith(InputStream key)
|
||||
throws SOPGPException.KeyIsProtected,
|
||||
SOPGPException.CertCannotSign,
|
||||
SOPGPException.KeyCannotSign,
|
||||
SOPGPException.UnsupportedAsymmetricAlgo,
|
||||
SOPGPException.BadData;
|
||||
|
||||
|
@ -50,7 +50,7 @@ public interface Encrypt {
|
|||
*/
|
||||
default Encrypt signWith(byte[] key)
|
||||
throws SOPGPException.KeyIsProtected,
|
||||
SOPGPException.CertCannotSign,
|
||||
SOPGPException.KeyCannotSign,
|
||||
SOPGPException.UnsupportedAsymmetricAlgo,
|
||||
SOPGPException.BadData {
|
||||
return signWith(new ByteArrayInputStream(key));
|
||||
|
|
|
@ -21,18 +21,18 @@ public interface ExtractCert {
|
|||
ExtractCert noArmor();
|
||||
|
||||
/**
|
||||
* Extract the cert from the provided key.
|
||||
* Extract the cert(s) from the provided key(s).
|
||||
*
|
||||
* @param keyInputStream input stream containing the encoding of an OpenPGP key
|
||||
* @return result containing the encoding of the keys cert
|
||||
* @param keyInputStream input stream containing the encoding of one or more OpenPGP keys
|
||||
* @return result containing the encoding of the keys certs
|
||||
*/
|
||||
Ready key(InputStream keyInputStream) throws IOException, SOPGPException.BadData;
|
||||
|
||||
/**
|
||||
* Extract the cert from the provided key.
|
||||
* Extract the cert(s) from the provided key(s).
|
||||
*
|
||||
* @param key byte array containing the encoding of an OpenPGP key
|
||||
* @return result containing the encoding of the keys cert
|
||||
* @param key byte array containing the encoding of one or more OpenPGP key
|
||||
* @return result containing the encoding of the keys certs
|
||||
*/
|
||||
default Ready key(byte[] key) throws IOException, SOPGPException.BadData {
|
||||
return key(new ByteArrayInputStream(key));
|
||||
|
|
|
@ -8,7 +8,8 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import sop.Ready;
|
||||
import sop.MicAlg;
|
||||
import sop.ReadyWithResult;
|
||||
import sop.enums.SignAs;
|
||||
import sop.exception.SOPGPException;
|
||||
|
||||
|
@ -31,17 +32,17 @@ public interface Sign {
|
|||
Sign mode(SignAs mode) throws SOPGPException.UnsupportedOption;
|
||||
|
||||
/**
|
||||
* Adds the signer key.
|
||||
* Add one or more signing keys.
|
||||
*
|
||||
* @param key input stream containing encoded key
|
||||
* @param key input stream containing encoded keys
|
||||
* @return builder instance
|
||||
*/
|
||||
Sign key(InputStream key) throws SOPGPException.KeyIsProtected, SOPGPException.BadData, IOException;
|
||||
|
||||
/**
|
||||
* Adds the signer key.
|
||||
* Add one or more signing keys.
|
||||
*
|
||||
* @param key byte array containing encoded key
|
||||
* @param key byte array containing encoded keys
|
||||
* @return builder instance
|
||||
*/
|
||||
default Sign key(byte[] key) throws SOPGPException.KeyIsProtected, SOPGPException.BadData, IOException {
|
||||
|
@ -54,7 +55,7 @@ public interface Sign {
|
|||
* @param data input stream containing data
|
||||
* @return ready
|
||||
*/
|
||||
Ready data(InputStream data) throws IOException, SOPGPException.ExpectedText;
|
||||
ReadyWithResult<MicAlg> data(InputStream data) throws IOException, SOPGPException.ExpectedText;
|
||||
|
||||
/**
|
||||
* Signs data.
|
||||
|
@ -62,7 +63,7 @@ public interface Sign {
|
|||
* @param data byte array containing data
|
||||
* @return ready
|
||||
*/
|
||||
default Ready data(byte[] data) throws IOException, SOPGPException.ExpectedText {
|
||||
default ReadyWithResult<MicAlg> data(byte[] data) throws IOException, SOPGPException.ExpectedText {
|
||||
return data(new ByteArrayInputStream(data));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,17 +29,17 @@ public interface Verify extends VerifySignatures {
|
|||
Verify notAfter(Date timestamp) throws SOPGPException.UnsupportedOption;
|
||||
|
||||
/**
|
||||
* Adds the verification cert.
|
||||
* Add one or more verification cert.
|
||||
*
|
||||
* @param cert input stream containing the encoded cert
|
||||
* @param cert input stream containing the encoded certs
|
||||
* @return builder instance
|
||||
*/
|
||||
Verify cert(InputStream cert) throws SOPGPException.BadData;
|
||||
|
||||
/**
|
||||
* Adds the verification cert.
|
||||
* Add one or more verification cert.
|
||||
*
|
||||
* @param cert byte array containing the encoded cert
|
||||
* @param cert byte array containing the encoded certs
|
||||
* @return builder instance
|
||||
*/
|
||||
default Verify cert(byte[] cert) throws SOPGPException.BadData {
|
||||
|
|
|
@ -8,15 +8,42 @@ public interface Version {
|
|||
|
||||
/**
|
||||
* Return the implementations name.
|
||||
* e.g. "SOP",
|
||||
*
|
||||
* @return implementation name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return the implementations version string.
|
||||
* Return the implementations short version string.
|
||||
* e.g. "1.0"
|
||||
*
|
||||
* @return version string
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Return version information about the used OpenPGP backend.
|
||||
* e.g. "Bouncycastle 1.70"
|
||||
*
|
||||
* @return backend version string
|
||||
*/
|
||||
String getBackendVersion();
|
||||
|
||||
/**
|
||||
* Return an extended version string containing multiple lines of version information.
|
||||
* The first line MUST match the information produced by {@link #getName()} and {@link #getVersion()}, but the rest of the text
|
||||
* has no defined structure.
|
||||
* Example:
|
||||
* <pre>
|
||||
* "SOP 1.0
|
||||
* Awesome PGP!
|
||||
* Using Bouncycastle 1.70
|
||||
* LibFoo 1.2.2
|
||||
* See https://pgp.example.org/sop/ for more information"
|
||||
* </pre>
|
||||
*
|
||||
* @return extended version string
|
||||
*/
|
||||
String getExtendedVersion();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue