Compare commits

...

2 commits

4 changed files with 45 additions and 9 deletions

View file

@ -1,6 +1,8 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredInputStream;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPApi; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -26,10 +28,11 @@ public class BCArmor
return new Ready() { return new Ready() {
@Override @Override
public void writeTo(@NotNull OutputStream outputStream) throws IOException { public void writeTo(@NotNull OutputStream outputStream) throws IOException {
InputStream decodeIn = PGPUtil.getDecoderStream(inputStream);
ArmoredOutputStream aOut = ArmoredOutputStream.builder() ArmoredOutputStream aOut = ArmoredOutputStream.builder()
.clearHeaders() .clearHeaders()
.build(outputStream); .build(outputStream);
Streams.pipeAll(inputStream, aOut); Streams.pipeAll(decodeIn, aOut);
aOut.close(); aOut.close();
} }
}; };

View file

@ -1,6 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPApi; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -26,9 +26,9 @@ public class BCDearmor
return new Ready() { return new Ready() {
@Override @Override
public void writeTo(@NotNull OutputStream outputStream) throws IOException { public void writeTo(@NotNull OutputStream outputStream) throws IOException {
ArmoredInputStream aIn = new ArmoredInputStream(inputStream); InputStream decodeIn = PGPUtil.getDecoderStream(inputStream);
Streams.pipeAll(aIn, outputStream); Streams.pipeAll(decodeIn, outputStream);
aIn.close(); decodeIn.close();
} }
}; };
} }

View file

@ -1,8 +1,11 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.MessageEncryptionMechanism;
import org.bouncycastle.openpgp.api.OpenPGPApi; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPEncryptionNegotiator;
import org.bouncycastle.openpgp.api.OpenPGPKey; 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;
@ -12,6 +15,7 @@ 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;
import sop.EncryptionResult; import sop.EncryptionResult;
import sop.Profile;
import sop.ReadyWithResult; import sop.ReadyWithResult;
import sop.SessionKey; import sop.SessionKey;
import sop.enums.EncryptAs; import sop.enums.EncryptAs;
@ -23,15 +27,25 @@ import java.io.InputStream;
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.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class BCEncrypt public class BCEncrypt
extends AbstractBCOperation extends AbstractBCOperation
implements Encrypt { implements Encrypt {
public static final Profile RFC4880_PROFILE = new Profile("rfc4880", "Follow the packet format of rfc4880");
public static final Profile RFC9580_PROFILE = new Profile("rfc9580", "Follow the packet format of rfc9580");
public static final List<Profile> PROFILES = Arrays.asList(
RFC4880_PROFILE.withAliases("default", "compatibility"),
RFC9580_PROFILE.withAliases("security", "performance"));
private final OpenPGPMessageGenerator mGen; private final OpenPGPMessageGenerator mGen;
private final List<OpenPGPKey> signingKeys = new ArrayList<>(); private final List<OpenPGPKey> signingKeys = new ArrayList<>();
private int signatureMode = PGPSignature.BINARY_DOCUMENT; private int signatureMode = PGPSignature.BINARY_DOCUMENT;
private boolean hasEncryptionMethod = false; private boolean hasEncryptionMethod = false;
private Profile profile = RFC9580_PROFILE;
public BCEncrypt(OpenPGPApi api) { public BCEncrypt(OpenPGPApi api) {
super(api); super(api);
@ -104,8 +118,13 @@ public class BCEncrypt
@NotNull @NotNull
@Override @Override
public Encrypt profile(@NotNull String s) { public Encrypt profile(@NotNull String s) {
// TODO: Implement for (Profile p : PROFILES) {
return this; if (p.getName().equals(s) || p.getAliases().contains(s)) {
profile = p;
return this;
}
}
throw new SOPGPException.UnsupportedProfile("encrypt", s);
} }
@NotNull @NotNull
@ -116,6 +135,21 @@ public class BCEncrypt
throw new SOPGPException.MissingArg("No encryption method provided."); throw new SOPGPException.MissingArg("No encryption method provided.");
} }
if (profile.getName().equals(RFC4880_PROFILE.getName())) {
mGen.setPublicKeyBasedEncryptionNegotiator(new OpenPGPEncryptionNegotiator() {
@Override
public MessageEncryptionMechanism negotiateEncryption(OpenPGPMessageGenerator configuration) {
return MessageEncryptionMechanism.integrityProtected(SymmetricKeyAlgorithmTags.AES_256);
}
});
mGen.setPasswordBasedEncryptionNegotiator(new OpenPGPEncryptionNegotiator() {
@Override
public MessageEncryptionMechanism negotiateEncryption(OpenPGPMessageGenerator configuration) {
return MessageEncryptionMechanism.integrityProtected(SymmetricKeyAlgorithmTags.AES_256);
}
});
}
for (OpenPGPKey key : signingKeys) { for (OpenPGPKey key : signingKeys) {
try { try {
mGen.addSigningKey(key, new SignatureParameters.Callback() { mGen.addSigningKey(key, new SignatureParameters.Callback() {

View file

@ -6,7 +6,6 @@ import sop.Profile;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import sop.operation.ListProfiles; import sop.operation.ListProfiles;
import java.util.Collections;
import java.util.List; import java.util.List;
public class BCListProfiles public class BCListProfiles
@ -24,7 +23,7 @@ public class BCListProfiles
case "generate-key": case "generate-key":
return BCGenerateKey.PROFILES; return BCGenerateKey.PROFILES;
case "encrypt": case "encrypt":
return Collections.emptyList(); return BCEncrypt.PROFILES;
} }
throw new SOPGPException.UnsupportedProfile(s); throw new SOPGPException.UnsupportedProfile(s);
} }