From 422806f622af9e7ce221f13287ffc88774b3e0a2 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 29 Nov 2016 19:22:06 +0100 Subject: [PATCH] ignore leading whitespace for pgp/inline messages in MessageDecryptVerifier (fixes #1823) --- .../k9/crypto/MessageDecryptVerifier.java | 17 +++- .../k9/crypto/MessageDecryptVerifierTest.java | 82 +++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java b/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java index 434c9078d..05bc32c20 100644 --- a/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java +++ b/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Stack; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import com.fsck.k9.mail.Body; @@ -188,13 +189,17 @@ public class MessageDecryptVerifier { return isPgpEncrypted || isPgpSigned; } - private static boolean isPartPgpInlineEncryptedOrSigned(Part part) { + @VisibleForTesting + static boolean isPartPgpInlineEncryptedOrSigned(Part part) { if (!part.isMimeType(TEXT_PLAIN) && !part.isMimeType(APPLICATION_PGP)) { return false; } String text = MessageExtractor.getTextFromPart(part, TEXT_LENGTH_FOR_INLINE_CHECK); - return !TextUtils.isEmpty(text) && - (text.startsWith(PGP_INLINE_START_MARKER) || text.startsWith(PGP_INLINE_SIGNED_START_MARKER)); + if (TextUtils.isEmpty(text)) { + return false; + } + text = text.trim(); + return text.startsWith(PGP_INLINE_START_MARKER) || text.startsWith(PGP_INLINE_SIGNED_START_MARKER); } public static boolean isPartPgpInlineEncrypted(@Nullable Part part) { @@ -205,7 +210,11 @@ public class MessageDecryptVerifier { return false; } String text = MessageExtractor.getTextFromPart(part, TEXT_LENGTH_FOR_INLINE_CHECK); - return !TextUtils.isEmpty(text) && text.startsWith(PGP_INLINE_START_MARKER); + if (TextUtils.isEmpty(text)) { + return false; + } + text = text.trim(); + return text.startsWith(PGP_INLINE_START_MARKER); } } diff --git a/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java index 3c97b479c..46394e4ef 100644 --- a/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java +++ b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java @@ -21,7 +21,9 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertSame; +import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -272,6 +274,86 @@ public class MessageDecryptVerifierTest { assertSame(getPart(message, 1), signedParts.get(0)); } + @Test + public void isPgpInlineMethods__withPgpInlineData__shouldReturnTrue() throws Exception { + String pgpInlineData = "-----BEGIN PGP MESSAGE-----\n" + + "Header: Value\n" + + "\n" + + "base64base64base64base64\n" + + "-----END PGP MESSAGE-----\n"; + + MimeMessage message = new MimeMessage(); + message.setBody(new TextBody(pgpInlineData)); + + assertTrue(MessageDecryptVerifier.isPartPgpInlineEncrypted(message)); + } + + @Test + public void isPgpInlineMethods__withEncryptedDataAndLeadingWhitespace__shouldReturnTrue() throws Exception { + String pgpInlineData = "\n \n \n" + + "-----BEGIN PGP MESSAGE-----\n" + + "Header: Value\n" + + "\n" + + "base64base64base64base64\n" + + "-----END PGP MESSAGE-----\n"; + + MimeMessage message = new MimeMessage(); + message.setBody(new TextBody(pgpInlineData)); + + assertTrue(MessageDecryptVerifier.isPartPgpInlineEncryptedOrSigned(message)); + assertTrue(MessageDecryptVerifier.isPartPgpInlineEncrypted(message)); + } + + @Test + public void isPgpInlineMethods__withEncryptedDataAndLeadingGarbage__shouldReturnFalse() throws Exception { + String pgpInlineData = "garbage!" + + "-----BEGIN PGP MESSAGE-----\n" + + "Header: Value\n" + + "\n" + + "base64base64base64base64\n" + + "-----END PGP MESSAGE-----\n"; + + MimeMessage message = new MimeMessage(); + message.setBody(new TextBody(pgpInlineData)); + + assertFalse(MessageDecryptVerifier.isPartPgpInlineEncryptedOrSigned(message)); + assertFalse(MessageDecryptVerifier.isPartPgpInlineEncrypted(message)); + } + + @Test + public void isPartPgpInlineEncryptedOrSigned__withSignedData__shouldReturnTrue() throws Exception { + String pgpInlineData = "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "Header: Value\n" + + "\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "Header: Value\n" + + "\n" + + "base64base64base64base64\n" + + "-----END PGP SIGNED MESSAGE-----\n"; + + MimeMessage message = new MimeMessage(); + message.setBody(new TextBody(pgpInlineData)); + + assertTrue(MessageDecryptVerifier.isPartPgpInlineEncryptedOrSigned(message)); + } + + @Test + public void isPartPgpInlineEncrypted__withSignedData__shouldReturnFalse() throws Exception { + String pgpInlineData = "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "Header: Value\n" + + "\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "Header: Value\n" + + "\n" + + "base64base64base64base64\n" + + "-----END PGP SIGNED MESSAGE-----\n"; + + MimeMessage message = new MimeMessage(); + message.setBody(new TextBody(pgpInlineData)); + + assertFalse(MessageDecryptVerifier.isPartPgpInlineEncrypted(message)); + } + MimeMessage messageFromBody(BodyPart bodyPart) throws MessagingException { MimeMessage message = new MimeMessage(); MimeMessageHelper.setBody(message, bodyPart.getBody());