mirror of
https://codeberg.org/PGPainless/bc-sop.git
synced 2025-09-09 19:29:41 +02:00
Fix key to passphrase mapping
This commit is contained in:
parent
6a8aafd056
commit
0a196432ff
6 changed files with 144 additions and 163 deletions
|
@ -1,97 +0,0 @@
|
||||||
package org.pgpainless.bouncycastle.sop;
|
|
||||||
|
|
||||||
import sop.Verification;
|
|
||||||
import sop.operation.DetachedVerify;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.SequenceInputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DetachedVerifyTest {
|
|
||||||
|
|
||||||
static String SIG = "-----BEGIN PGP SIGNATURE-----\n" +
|
|
||||||
"\n" +
|
|
||||||
"wnUEABYKAB0WIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCZ1mi4QAKCRDyMVUMT0fj\n" +
|
|
||||||
"jun3AP9ZiRPXlow7ywR3D7nC4/GGUC+PueZ1GkcXDtE8zbAiTgEArkOQO8qhC0QG\n" +
|
|
||||||
"K6TKEPJM07Zie/kgcGyh8HfSpbunwAXCwPMEAAEKAB0WIQTRpm4aI7GCyZgPeIz7\n" +
|
|
||||||
"/MgqAV5zMAUCZ1mi4QAKCRD7/MgqAV5zMI51C/sFv6vjBbxdgNMp1qwJ3AqMhbtV\n" +
|
|
||||||
"WJ7z8HJraT+dW0VKYmib7H7lL3x3gTC85VaOWGU3mqhxZLQVi6j99pbbZjGXJADF\n" +
|
|
||||||
"e5E1S+tp6js56OI4fY/kchLMcz1JxgjSJPJnlyEXy5C2/2RlI1JmpUn6Y8YOlNhZ\n" +
|
|
||||||
"Vbov36QB2ILt+k62ElQeHgWQYqWWMmxmdk9wipNKYfBoQNVwJNICDjI+XlwL4cGw\n" +
|
|
||||||
"nyg3cdgkKXikPFEBhlApI5HmX4jOv68gReEMMTaZoQoRD8kzg9m7KC6BqHpG0TAZ\n" +
|
|
||||||
"Bz5TzZrxW1LdXj/tKqNONcldHHzO4mZIUkdOowGMBmEf0kZ2nVHZGaWE1T7IqJPo\n" +
|
|
||||||
"cIPtZB+EpDCcPQN35ekC0B1ilDd07IulNHOdbhI7xu0/eQb6dGpkzkak3OpWbGtX\n" +
|
|
||||||
"rKfxljqLFTnnJfM95UlrlCWwEplRZ2q4QhXi8/mRM/Szz5D3KGd7hnLRnr42J4Dr\n" +
|
|
||||||
"j/XWKoSXmFZ5t6CBq7BgubE1uO2ToRWOlas+jNE=\n" +
|
|
||||||
"=bJ8+\n" +
|
|
||||||
"-----END PGP SIGNATURE-----";
|
|
||||||
static String ALICE = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
|
||||||
"Comment: Alice's OpenPGP certificate\n" +
|
|
||||||
"\n" +
|
|
||||||
"mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" +
|
|
||||||
"b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE\n" +
|
|
||||||
"ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy\n" +
|
|
||||||
"MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO\n" +
|
|
||||||
"dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4\n" +
|
|
||||||
"OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s\n" +
|
|
||||||
"E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb\n" +
|
|
||||||
"DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn\n" +
|
|
||||||
"0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=\n" +
|
|
||||||
"=iIGO\n" +
|
|
||||||
"-----END PGP PUBLIC KEY BLOCK-----";
|
|
||||||
static String BOB = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
|
||||||
"Comment: Bob's OpenPGP certificate\n" +
|
|
||||||
"\n" +
|
|
||||||
"mQGNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv\n" +
|
|
||||||
"/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz\n" +
|
|
||||||
"/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/\n" +
|
|
||||||
"5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3\n" +
|
|
||||||
"X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv\n" +
|
|
||||||
"9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0\n" +
|
|
||||||
"qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb\n" +
|
|
||||||
"SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb\n" +
|
|
||||||
"vLIwa3T4CyshfT0AEQEAAbQhQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w\n" +
|
|
||||||
"bGU+iQHOBBMBCgA4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE0aZuGiOx\n" +
|
|
||||||
"gsmYD3iM+/zIKgFeczAFAl2lnvoACgkQ+/zIKgFeczBvbAv/VNk90a6hG8Od9xTz\n" +
|
|
||||||
"XxH5YRFUSGfIA1yjPIVOnKqhMwps2U+sWE3urL+MvjyQRlyRV8oY9IOhQ5Esm6DO\n" +
|
|
||||||
"ZYrTnE7qVETm1ajIAP2OFChEc55uH88x/anpPOXOJY7S8jbn3naC9qad75BrZ+3g\n" +
|
|
||||||
"9EBUWiy5p8TykP05WSnSxNRt7vFKLfEB4nGkehpwHXOVF0CRNwYle42bg8lpmdXF\n" +
|
|
||||||
"DcCZCi+qEbafmTQzkAqyzS3nCh3IAqq6Y0kBuaKLm2tSNUOlZbD+OHYQNZ5Jix7c\n" +
|
|
||||||
"ZUzs6Xh4+I55NRWl5smrLq66yOQoFPy9jot/Qxikx/wP3MsAzeGaZSEPc0fHp5G1\n" +
|
|
||||||
"6rlGbxQ3vl8/usUV7W+TMEMljgwd5x8POR6HC8EaCDfVnUBCPi/Gv+egLjsIbPJZ\n" +
|
|
||||||
"ZEroiE40e6/UoCiQtlpQB5exPJYSd1Q1txCwueih99PHepsDhmUQKiACszNU+RRo\n" +
|
|
||||||
"zAYau2VdHqnRJ7QYdxHDiH49jPK4NTMyb/tJh2TiIwcmsIpGuQGNBF2lnPIBDADW\n" +
|
|
||||||
"ML9cbGMrp12CtF9b2P6z9TTT74S8iyBOzaSvdGDQY/sUtZXRg21HWamXnn9sSXvI\n" +
|
|
||||||
"DEINOQ6A9QxdxoqWdCHrOuW3ofneYXoG+zeKc4dC86wa1TR2q9vW+RMXSO4uImA+\n" +
|
|
||||||
"Uzula/6k1DogDf28qhCxMwG/i/m9g1c/0aApuDyKdQ1PXsHHNlgd/Dn6rrd5y2AO\n" +
|
|
||||||
"baifV7wIhEJnvqgFXDN2RXGjLeCOHV4Q2WTYPg/S4k1nMXVDwZXrvIsA0YwIMgIT\n" +
|
|
||||||
"86Rafp1qKlgPNbiIlC1g9RY/iFaGN2b4Ir6GDohBQSfZW2+LXoPZuVE/wGlQ01rh\n" +
|
|
||||||
"827KVZW4lXvqsge+wtnWlszcselGATyzqOK9LdHPdZGzROZYI2e8c+paLNDdVPL6\n" +
|
|
||||||
"vdRBUnkCaEkOtl1mr2JpQi5nTU+gTX4IeInC7E+1a9UDF/Y85ybUz8XV8rUnR76U\n" +
|
|
||||||
"qVC7KidNepdHbZjjXCt8/Zo+Tec9JNbYNQB/e9ExmDntmlHEsSEQzFwzj8sxH48A\n" +
|
|
||||||
"EQEAAYkBtgQYAQoAIBYhBNGmbhojsYLJmA94jPv8yCoBXnMwBQJdpZzyAhsMAAoJ\n" +
|
|
||||||
"EPv8yCoBXnMw6f8L/26C34dkjBffTzMj5Bdzm8MtF67OYneJ4TQMw7+41IL4rVcS\n" +
|
|
||||||
"KhIhk/3Ud5knaRtP2ef1+5F66h9/RPQOJ5+tvBwhBAcUWSupKnUrdVaZQanYmtSx\n" +
|
|
||||||
"cVV2PL9+QEiNN3tzluhaWO//rACxJ+K/ZXQlIzwQVTpNhfGzAaMVV9zpf3u0k14i\n" +
|
|
||||||
"tcv6alKY8+rLZvO1wIIeRZLmU0tZDD5HtWDvUV7rIFI1WuoLb+KZgbYn3OWjCPHV\n" +
|
|
||||||
"dTrdZ2CqnZbG3SXw6awH9bzRLV9EXkbhIMez0deCVdeo+wFFklh8/5VK2b0vk/+w\n" +
|
|
||||||
"qMJxfpa1lHvJLobzOP9fvrswsr92MA2+k901WeISR7qEzcI0Fdg8AyFAExaEK6Vy\n" +
|
|
||||||
"jP7SXGLwvfisw34OxuZr3qmx1Sufu4toH3XrB7QJN8XyqqbsGxUCBqWif9RSK4xj\n" +
|
|
||||||
"zRTe56iPeiSJJOIciMP9i2ldI+KgLycyeDvGoBj0HCLO3gVaBe4ubVrj5KjhX2PV\n" +
|
|
||||||
"NEJd3XZRzaXZE2aAMQ==\n" +
|
|
||||||
"=NXei\n" +
|
|
||||||
"-----END PGP PUBLIC KEY BLOCK-----";
|
|
||||||
static String MSG = "Hello World :)";
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
BouncyCastleSOP sop = new BouncyCastleSOP();
|
|
||||||
ByteArrayInputStream sigIn = new ByteArrayInputStream(SIG.getBytes(StandardCharsets.UTF_8));
|
|
||||||
DetachedVerify verify = sop.detachedVerify();
|
|
||||||
verify.signatures(sigIn);
|
|
||||||
verify.cert(new ByteArrayInputStream(ALICE.getBytes(StandardCharsets.UTF_8)))
|
|
||||||
.cert(new ByteArrayInputStream(BOB.getBytes(StandardCharsets.UTF_8)));
|
|
||||||
List<Verification> verif = verify.data(new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ package org.pgpainless.bouncycastle.sop.operation;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
@ -16,6 +17,7 @@ import sop.operation.Decrypt;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class BCDecrypt
|
public class BCDecrypt
|
||||||
|
@ -24,8 +26,6 @@ public class BCDecrypt
|
||||||
|
|
||||||
private final OpenPGPMessageProcessor processor;
|
private final OpenPGPMessageProcessor processor;
|
||||||
|
|
||||||
private char[] keyPassword;
|
|
||||||
|
|
||||||
public BCDecrypt(OpenPGPApi api) {
|
public BCDecrypt(OpenPGPApi api) {
|
||||||
super(api);
|
super(api);
|
||||||
this.processor = api.decryptAndOrVerifyMessage();
|
this.processor = api.decryptAndOrVerifyMessage();
|
||||||
|
@ -33,7 +33,9 @@ public class BCDecrypt
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ReadyWithResult<DecryptionResult> ciphertext(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt, SOPGPException.KeyIsProtected, IOException {
|
public ReadyWithResult<DecryptionResult> ciphertext(@NotNull InputStream inputStream)
|
||||||
|
throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt,
|
||||||
|
SOPGPException.KeyIsProtected {
|
||||||
return new ReadyWithResult<>() {
|
return new ReadyWithResult<>() {
|
||||||
@Override
|
@Override
|
||||||
public DecryptionResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
|
public DecryptionResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
|
||||||
|
@ -89,16 +91,23 @@ public class BCDecrypt
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Decrypt withKey(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
|
public Decrypt withKey(@NotNull InputStream inputStream)
|
||||||
processor.addDecryptionKey(parseKey(inputStream), keyPassword);
|
throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
|
||||||
|
OpenPGPKey key = api.readKeyOrCertificate().parseKey(inputStream);
|
||||||
|
processor.addDecryptionKey(key);
|
||||||
|
|
||||||
|
if (key.getEncryptionKeys().isEmpty()) {
|
||||||
|
throw new SOPGPException.CertCannotEncrypt("No decryption key found.");
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Decrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
public Decrypt withKeyPassword(@NotNull byte[] bytes)
|
||||||
String passphrase = new String(bytes);
|
throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
||||||
this.keyPassword = passphrase.toCharArray();
|
char[] pw = new String(bytes, StandardCharsets.UTF_8).toCharArray();
|
||||||
|
processor.addDecryptionKeyPassphrase(pw);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import sop.operation.DetachedSign;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BCDetachedSign
|
public class BCDetachedSign
|
||||||
|
@ -29,8 +31,7 @@ public class BCDetachedSign
|
||||||
|
|
||||||
private final OpenPGPDetachedSignatureGenerator sigGen;
|
private final OpenPGPDetachedSignatureGenerator sigGen;
|
||||||
private boolean armored = true;
|
private boolean armored = true;
|
||||||
private char[] keyPassword = null;
|
private List<OpenPGPKey> signingKeys = new ArrayList<>();
|
||||||
|
|
||||||
private int signatureMode = PGPSignature.BINARY_DOCUMENT;
|
private int signatureMode = PGPSignature.BINARY_DOCUMENT;
|
||||||
|
|
||||||
public BCDetachedSign(OpenPGPApi api) {
|
public BCDetachedSign(OpenPGPApi api) {
|
||||||
|
@ -40,12 +41,21 @@ public class BCDetachedSign
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ReadyWithResult<SigningResult> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
|
public ReadyWithResult<SigningResult> data(@NotNull InputStream inputStream)
|
||||||
|
throws SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
|
||||||
return new ReadyWithResult<SigningResult>() {
|
return new ReadyWithResult<SigningResult>() {
|
||||||
@Override
|
@Override
|
||||||
public SigningResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
|
public SigningResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
for (OpenPGPKey signingKey : signingKeys) {
|
||||||
|
sigGen.addSigningKey(signingKey, new SignatureParameters.Callback() {
|
||||||
|
@Override
|
||||||
|
public SignatureParameters apply(SignatureParameters parameters) {
|
||||||
|
return parameters.setSignatureType(signatureMode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
List<OpenPGPSignature.OpenPGPDocumentSignature> signatures = sigGen.sign(inputStream);
|
List<OpenPGPSignature.OpenPGPDocumentSignature> signatures = sigGen.sign(inputStream);
|
||||||
OutputStream aOut = null;
|
OutputStream aOut = null;
|
||||||
OutputStream pOut;
|
OutputStream pOut;
|
||||||
|
@ -72,7 +82,11 @@ public class BCDetachedSign
|
||||||
aOut.close();
|
aOut.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SigningResult(MicAlg.fromHashAlgorithmId(signatures.get(0).getSignature().getHashAlgorithm()));
|
return new SigningResult(MicAlg.fromHashAlgorithmId(
|
||||||
|
signatures.get(0).getSignature().getHashAlgorithm()));
|
||||||
|
}
|
||||||
|
catch (InvalidSigningKeyException e) {
|
||||||
|
throw new SOPGPException.KeyCannotSign("Key cannot sign.", e);
|
||||||
}
|
}
|
||||||
catch (PGPException e)
|
catch (PGPException e)
|
||||||
{
|
{
|
||||||
|
@ -104,34 +118,17 @@ public class BCDetachedSign
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DetachedSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
|
public DetachedSign key(@NotNull InputStream inputStream)
|
||||||
try
|
throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo {
|
||||||
{
|
OpenPGPKey key = parseKey(inputStream);
|
||||||
OpenPGPKey key = parseKey(inputStream);
|
signingKeys.add(key);
|
||||||
OpenPGPKey.OpenPGPSecretKey signingKey = key.getSecretKey(key.getSigningKeys().get(0));
|
|
||||||
sigGen.addSigningKey(signingKey,
|
|
||||||
k -> keyPassword,
|
|
||||||
new SignatureParameters.Callback() {
|
|
||||||
@Override
|
|
||||||
public SignatureParameters apply(SignatureParameters parameters) {
|
|
||||||
return parameters.setSignatureType(signatureMode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (InvalidSigningKeyException e)
|
|
||||||
{
|
|
||||||
throw new SOPGPException.KeyCannotSign("Key cannot sign", e);
|
|
||||||
}
|
|
||||||
catch (PGPException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DetachedSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
public DetachedSign withKeyPassword(@NotNull byte[] bytes)
|
||||||
keyPassword = new String(bytes).toCharArray();
|
throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
||||||
|
sigGen.addKeyPassphrase(new String(bytes, StandardCharsets.UTF_8).toCharArray());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package org.pgpainless.bouncycastle.sop.operation;
|
package org.pgpainless.bouncycastle.sop.operation;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
|
||||||
|
import org.bouncycastle.openpgp.api.SignatureParameters;
|
||||||
import org.bouncycastle.openpgp.api.exception.InvalidEncryptionKeyException;
|
import org.bouncycastle.openpgp.api.exception.InvalidEncryptionKeyException;
|
||||||
import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException;
|
import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
@ -18,12 +21,16 @@ import sop.operation.Encrypt;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BCEncrypt
|
public class BCEncrypt
|
||||||
extends AbstractBCOperation
|
extends AbstractBCOperation
|
||||||
implements Encrypt {
|
implements Encrypt {
|
||||||
private final OpenPGPMessageGenerator mGen;
|
private final OpenPGPMessageGenerator mGen;
|
||||||
private char[] keyPassword;
|
private final List<OpenPGPKey> signingKeys = new ArrayList<>();
|
||||||
|
private int signatureMode = PGPSignature.BINARY_DOCUMENT;
|
||||||
|
|
||||||
public BCEncrypt(OpenPGPApi api) {
|
public BCEncrypt(OpenPGPApi api) {
|
||||||
super(api);
|
super(api);
|
||||||
|
@ -33,7 +40,15 @@ public class BCEncrypt
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Encrypt mode(@NotNull EncryptAs encryptAs) throws SOPGPException.UnsupportedOption {
|
public Encrypt mode(@NotNull EncryptAs encryptAs) throws SOPGPException.UnsupportedOption {
|
||||||
// TODO: Implement
|
switch (encryptAs)
|
||||||
|
{
|
||||||
|
case text:
|
||||||
|
signatureMode = PGPSignature.CANONICAL_TEXT_DOCUMENT;
|
||||||
|
break;
|
||||||
|
case binary:
|
||||||
|
signatureMode = PGPSignature.BINARY_DOCUMENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,32 +61,35 @@ public class BCEncrypt
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Encrypt signWith(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
public Encrypt signWith(@NotNull InputStream inputStream)
|
||||||
try {
|
throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData,
|
||||||
mGen.addSigningKey(parseKey(inputStream), k -> keyPassword);
|
IOException {
|
||||||
} catch (InvalidSigningKeyException e) {
|
OpenPGPKey key = api.readKeyOrCertificate().parseKey(inputStream);
|
||||||
throw new SOPGPException.KeyCannotSign("Key cannot sign", e);
|
signingKeys.add(key);
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Encrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
public Encrypt withKeyPassword(@NotNull byte[] bytes)
|
||||||
this.keyPassword = new String(bytes).toCharArray();
|
throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
||||||
|
mGen.addKeyPassphrase(new String(bytes, StandardCharsets.UTF_8).toCharArray());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Encrypt withPassword(@NotNull String s) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
public Encrypt withPassword(@NotNull String s)
|
||||||
|
throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
||||||
mGen.addEncryptionPassphrase(s.toCharArray());
|
mGen.addEncryptionPassphrase(s.toCharArray());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Encrypt withCert(@NotNull InputStream inputStream) throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
public Encrypt withCert(@NotNull InputStream inputStream)
|
||||||
|
throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
|
||||||
try {
|
try {
|
||||||
mGen.addEncryptionCertificate(parseCertificate(inputStream));
|
mGen.addEncryptionCertificate(parseCertificate(inputStream));
|
||||||
} catch (InvalidEncryptionKeyException e) {
|
} catch (InvalidEncryptionKeyException e) {
|
||||||
|
@ -89,7 +107,21 @@ public class BCEncrypt
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ReadyWithResult<EncryptionResult> plaintext(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected {
|
public ReadyWithResult<EncryptionResult> plaintext(@NotNull InputStream inputStream)
|
||||||
|
throws SOPGPException.KeyIsProtected {
|
||||||
|
for (OpenPGPKey key : signingKeys) {
|
||||||
|
try {
|
||||||
|
mGen.addSigningKey(key, new SignatureParameters.Callback() {
|
||||||
|
@Override
|
||||||
|
public SignatureParameters apply(SignatureParameters parameters) {
|
||||||
|
return parameters.setSignatureType(signatureMode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (InvalidSigningKeyException e) {
|
||||||
|
throw new SOPGPException.KeyCannotSign("Key cannot sign", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new ReadyWithResult<EncryptionResult>() {
|
return new ReadyWithResult<EncryptionResult>() {
|
||||||
SessionKey sessionKey = null;
|
SessionKey sessionKey = null;
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,7 +12,9 @@ import sop.operation.GenerateKey;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BCGenerateKey
|
public class BCGenerateKey
|
||||||
extends AbstractBCOperation
|
extends AbstractBCOperation
|
||||||
|
@ -20,7 +22,7 @@ public class BCGenerateKey
|
||||||
|
|
||||||
private boolean armor = true;
|
private boolean armor = true;
|
||||||
private boolean signOnly = false;
|
private boolean signOnly = false;
|
||||||
private String userId;
|
private final List<String> userIds = new ArrayList<>();
|
||||||
private char[] passphrase;
|
private char[] passphrase;
|
||||||
|
|
||||||
public BCGenerateKey(OpenPGPApi api) {
|
public BCGenerateKey(OpenPGPApi api) {
|
||||||
|
@ -29,13 +31,13 @@ public class BCGenerateKey
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
|
public Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo {
|
||||||
return new Ready()
|
return new Ready()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(@NotNull OutputStream outputStream) throws IOException
|
public void writeTo(@NotNull OutputStream outputStream) throws IOException
|
||||||
{
|
{
|
||||||
OpenPGPV6KeyGenerator generator = null;
|
OpenPGPV6KeyGenerator generator;
|
||||||
try {
|
try {
|
||||||
generator = api.generateKey(new Date());
|
generator = api.generateKey(new Date());
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
|
@ -44,14 +46,20 @@ public class BCGenerateKey
|
||||||
OpenPGPKey key;
|
OpenPGPKey key;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
OpenPGPV6KeyGenerator.WithPrimaryKey builder;
|
||||||
if (signOnly)
|
if (signOnly)
|
||||||
{
|
{
|
||||||
key = generator.signOnlyKey().build(passphrase);
|
builder = generator.signOnlyKey();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
key = generator.ed25519x25519Key(userId).build(passphrase);
|
builder = generator.ed25519x25519Key(null);
|
||||||
}
|
}
|
||||||
|
for (String userId : userIds)
|
||||||
|
{
|
||||||
|
builder.addUserId(userId);
|
||||||
|
}
|
||||||
|
key = builder.build(passphrase);
|
||||||
}
|
}
|
||||||
catch (PGPException e)
|
catch (PGPException e)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +88,7 @@ public class BCGenerateKey
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public GenerateKey userId(@NotNull String s) {
|
public GenerateKey userId(@NotNull String s) {
|
||||||
this.userId = s;
|
this.userIds.add(s);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package org.pgpainless.bouncycastle.sop.operation;
|
package org.pgpainless.bouncycastle.sop.operation;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
|
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
|
||||||
|
import org.bouncycastle.openpgp.api.SignatureParameters;
|
||||||
import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException;
|
import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -15,6 +18,9 @@ import sop.operation.InlineSign;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BCInlineSign
|
public class BCInlineSign
|
||||||
extends AbstractBCOperation
|
extends AbstractBCOperation
|
||||||
|
@ -22,7 +28,9 @@ public class BCInlineSign
|
||||||
{
|
{
|
||||||
|
|
||||||
private final OpenPGPMessageGenerator mGen;
|
private final OpenPGPMessageGenerator mGen;
|
||||||
private char[] keyPassword;
|
private final List<OpenPGPKey> signingKeys = new ArrayList<>();
|
||||||
|
|
||||||
|
private int signingMode = PGPSignature.BINARY_DOCUMENT;
|
||||||
|
|
||||||
public BCInlineSign(OpenPGPApi api) {
|
public BCInlineSign(OpenPGPApi api) {
|
||||||
super(api);
|
super(api);
|
||||||
|
@ -31,7 +39,20 @@ public class BCInlineSign
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Ready data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
|
public Ready data(@NotNull InputStream inputStream)
|
||||||
|
throws SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
|
||||||
|
for (OpenPGPKey key : signingKeys) {
|
||||||
|
try {
|
||||||
|
mGen.addSigningKey(key, new SignatureParameters.Callback() {
|
||||||
|
@Override
|
||||||
|
public SignatureParameters apply(SignatureParameters parameters) {
|
||||||
|
return parameters.setSignatureType(signingMode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (InvalidSigningKeyException e) {
|
||||||
|
throw new SOPGPException.KeyCannotSign("Key cannot sign.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return new Ready() {
|
return new Ready() {
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(@NotNull OutputStream outputStream) throws IOException {
|
public void writeTo(@NotNull OutputStream outputStream) throws IOException {
|
||||||
|
@ -48,7 +69,18 @@ public class BCInlineSign
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public InlineSign mode(@NotNull InlineSignAs inlineSignAs) throws SOPGPException.UnsupportedOption {
|
public InlineSign mode(@NotNull InlineSignAs inlineSignAs)
|
||||||
|
throws SOPGPException.UnsupportedOption {
|
||||||
|
switch (inlineSignAs)
|
||||||
|
{
|
||||||
|
case text:
|
||||||
|
signingMode = PGPSignature.CANONICAL_TEXT_DOCUMENT;
|
||||||
|
break;
|
||||||
|
case binary:
|
||||||
|
signingMode = PGPSignature.BINARY_DOCUMENT;
|
||||||
|
break;
|
||||||
|
// TODO: Cleartext Signature Framework
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,18 +91,18 @@ public class BCInlineSign
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InlineSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
|
public InlineSign key(@NotNull InputStream inputStream)
|
||||||
try {
|
throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo,
|
||||||
mGen.addSigningKey(api.readKeyOrCertificate().parseKey(inputStream), k -> keyPassword);
|
IOException {
|
||||||
} catch (InvalidSigningKeyException e) {
|
OpenPGPKey key = api.readKeyOrCertificate().parseKey(inputStream);
|
||||||
throw new SOPGPException.KeyCannotSign("Key cannot sign.", e);
|
signingKeys.add(key);
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InlineSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
public InlineSign withKeyPassword(@NotNull byte[] bytes)
|
||||||
this.keyPassword = new String(bytes).toCharArray();
|
throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
|
||||||
|
mGen.addKeyPassphrase(new String(bytes, StandardCharsets.UTF_8).toCharArray());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue