diff --git a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCArmor.java b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCArmor.java index 9ac8ba2..66f52a9 100644 --- a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCArmor.java +++ b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCArmor.java @@ -1,6 +1,8 @@ package org.pgpainless.bouncycastle.sop.operation; +import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.api.OpenPGPApi; import org.bouncycastle.util.io.Streams; import org.jetbrains.annotations.NotNull; @@ -26,10 +28,11 @@ public class BCArmor return new Ready() { @Override public void writeTo(@NotNull OutputStream outputStream) throws IOException { + InputStream decodeIn = PGPUtil.getDecoderStream(inputStream); ArmoredOutputStream aOut = ArmoredOutputStream.builder() .clearHeaders() .build(outputStream); - Streams.pipeAll(inputStream, aOut); + Streams.pipeAll(decodeIn, aOut); aOut.close(); } }; diff --git a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCDearmor.java b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCDearmor.java index 8bfda06..f4c94fc 100644 --- a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCDearmor.java +++ b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCDearmor.java @@ -1,6 +1,6 @@ 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.util.io.Streams; import org.jetbrains.annotations.NotNull; @@ -26,9 +26,9 @@ public class BCDearmor return new Ready() { @Override public void writeTo(@NotNull OutputStream outputStream) throws IOException { - ArmoredInputStream aIn = new ArmoredInputStream(inputStream); - Streams.pipeAll(aIn, outputStream); - aIn.close(); + InputStream decodeIn = PGPUtil.getDecoderStream(inputStream); + Streams.pipeAll(decodeIn, outputStream); + decodeIn.close(); } }; } diff --git a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCEncrypt.java b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCEncrypt.java index beaa9a7..691f815 100644 --- a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCEncrypt.java +++ b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCEncrypt.java @@ -1,8 +1,11 @@ package org.pgpainless.bouncycastle.sop.operation; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.api.MessageEncryptionMechanism; import org.bouncycastle.openpgp.api.OpenPGPApi; +import org.bouncycastle.openpgp.api.OpenPGPEncryptionNegotiator; import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator; 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.jetbrains.annotations.NotNull; import sop.EncryptionResult; +import sop.Profile; import sop.ReadyWithResult; import sop.SessionKey; import sop.enums.EncryptAs; @@ -23,15 +27,25 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class BCEncrypt extends AbstractBCOperation 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 PROFILES = Arrays.asList( + RFC4880_PROFILE.withAliases("default", "compatibility"), + RFC9580_PROFILE.withAliases("security", "performance")); + private final OpenPGPMessageGenerator mGen; private final List signingKeys = new ArrayList<>(); private int signatureMode = PGPSignature.BINARY_DOCUMENT; private boolean hasEncryptionMethod = false; + private Profile profile = RFC9580_PROFILE; public BCEncrypt(OpenPGPApi api) { super(api); @@ -104,8 +118,13 @@ public class BCEncrypt @NotNull @Override public Encrypt profile(@NotNull String s) { - // TODO: Implement - return this; + for (Profile p : PROFILES) { + if (p.getName().equals(s) || p.getAliases().contains(s)) { + profile = p; + return this; + } + } + throw new SOPGPException.UnsupportedProfile("encrypt", s); } @NotNull @@ -116,6 +135,21 @@ public class BCEncrypt 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) { try { mGen.addSigningKey(key, new SignatureParameters.Callback() { diff --git a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCListProfiles.java b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCListProfiles.java index d94b365..65c768f 100644 --- a/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCListProfiles.java +++ b/bc-sop-api/src/main/java/org/pgpainless/bouncycastle/sop/operation/BCListProfiles.java @@ -6,7 +6,6 @@ import sop.Profile; import sop.exception.SOPGPException; import sop.operation.ListProfiles; -import java.util.Collections; import java.util.List; public class BCListProfiles @@ -24,7 +23,7 @@ public class BCListProfiles case "generate-key": return BCGenerateKey.PROFILES; case "encrypt": - return Collections.emptyList(); + return BCEncrypt.PROFILES; } throw new SOPGPException.UnsupportedProfile(s); }