diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/algorithm/negotiation/EncryptionMechanismNegotiator.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/algorithm/negotiation/EncryptionMechanismNegotiator.kt index 238e3212..58293ca5 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/algorithm/negotiation/EncryptionMechanismNegotiator.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/algorithm/negotiation/EncryptionMechanismNegotiator.kt @@ -41,6 +41,10 @@ fun interface EncryptionMechanismNegotiator { return override } + if (features.isEmpty()) { + return policy.messageEncryptionAlgorithmPolicy.symmetricFallbackMechanism + } + // If all support SEIPD2, use SEIPD2 if (features.all { it.contains(Feature.MODIFICATION_DETECTION_2) }) { // Find best supported algorithm combination diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptRoundTripTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptRoundTripTest.java index 30616b22..185690cc 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptRoundTripTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptRoundTripTest.java @@ -9,14 +9,24 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.api.MessageEncryptionMechanism; import org.bouncycastle.util.io.Streams; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.pgpainless.PGPainless; +import org.pgpainless.decryption_verification.ConsumerOptions; +import org.pgpainless.decryption_verification.DecryptionStream; +import org.pgpainless.decryption_verification.MessageMetadata; +import org.pgpainless.encryption_signing.EncryptionStream; +import org.pgpainless.util.Passphrase; import sop.ByteArrayAndResult; import sop.DecryptionResult; import sop.SOP; @@ -116,7 +126,7 @@ public class EncryptDecryptRoundTripTest { } @Test - public void basicRoundTripWithPassword() throws IOException { + public void basicRoundTripWithPassword() throws IOException, PGPException { byte[] encrypted = sop.encrypt() .withPassword("passphr4s3") .plaintext(message) @@ -136,6 +146,26 @@ public class EncryptDecryptRoundTripTest { .isEmpty(); } + @Test + public void verifySymmetricMessageEncryptionUsesSEIPDv1WithAES128() throws IOException, PGPException { + byte[] encrypted = sop.encrypt() + .withPassword("passphr4s3") + .plaintext(message) + .toByteArrayAndResult() + .getBytes(); + + // Verify encryption mechanism + DecryptionStream decIn = PGPainless.getInstance().processMessage() + .onInputStream(new ByteArrayInputStream(encrypted)) + .withOptions(ConsumerOptions.get().addMessagePassphrase(Passphrase.fromPassword("passphr4s3"))); + Streams.drain(decIn); + decIn.close(); + MessageMetadata metadata = decIn.getMetadata(); + assertEquals( + MessageEncryptionMechanism.integrityProtected(SymmetricKeyAlgorithmTags.AES_128), + metadata.getEncryptionMechanism()); + } + @Test public void roundTripWithDecryptionPasswordContainingWhitespace() throws IOException { ByteArrayAndResult bytesAndResult = sop.decrypt()