Repo created
This commit is contained in:
parent
75dc487a7a
commit
39c29d175b
6317 changed files with 388324 additions and 2 deletions
11
legacy/crypto-openpgp/build.gradle.kts
Normal file
11
legacy/crypto-openpgp/build.gradle.kts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.android)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.legacy.core)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.fsck.k9.crypto.openpgp"
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.fsck.k9.crypto.openpgp;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.fsck.k9.crypto.MessageCryptoStructureDetector;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.message.extractors.TextPartFinder;
|
||||
|
||||
import static com.fsck.k9.mail.internet.MimeUtility.isSameMimeType;
|
||||
|
||||
|
||||
//FIXME: Make this only detect OpenPGP messages. Move support for S/MIME messages to separate module.
|
||||
class EncryptionDetector {
|
||||
private final TextPartFinder textPartFinder;
|
||||
|
||||
|
||||
EncryptionDetector(TextPartFinder textPartFinder) {
|
||||
this.textPartFinder = textPartFinder;
|
||||
}
|
||||
|
||||
public boolean isEncrypted(@NonNull Message message) {
|
||||
return isPgpMimeOrSMimeEncrypted(message) || containsInlinePgpEncryptedText(message);
|
||||
}
|
||||
|
||||
private boolean isPgpMimeOrSMimeEncrypted(Message message) {
|
||||
return containsPartWithMimeType(message, "multipart/encrypted", "application/pkcs7-mime");
|
||||
}
|
||||
|
||||
private boolean containsInlinePgpEncryptedText(Message message) {
|
||||
Part textPart = textPartFinder.findFirstTextPart(message);
|
||||
return MessageCryptoStructureDetector.isPartPgpInlineEncrypted(textPart);
|
||||
}
|
||||
|
||||
private boolean containsPartWithMimeType(Part part, String... wantedMimeTypes) {
|
||||
String mimeType = part.getMimeType();
|
||||
if (isMimeTypeAnyOf(mimeType, wantedMimeTypes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Body body = part.getBody();
|
||||
if (body instanceof Multipart) {
|
||||
Multipart multipart = (Multipart) body;
|
||||
for (BodyPart bodyPart : multipart.getBodyParts()) {
|
||||
if (containsPartWithMimeType(bodyPart, wantedMimeTypes)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isMimeTypeAnyOf(String mimeType, String... wantedMimeTypes) {
|
||||
for (String wantedMimeType : wantedMimeTypes) {
|
||||
if (isSameMimeType(mimeType, wantedMimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.fsck.k9.crypto.openpgp
|
||||
|
||||
import com.fsck.k9.crypto.EncryptionExtractor
|
||||
import com.fsck.k9.crypto.EncryptionResult
|
||||
import com.fsck.k9.mail.Message
|
||||
import com.fsck.k9.message.extractors.TextPartFinder
|
||||
|
||||
class OpenPgpEncryptionExtractor internal constructor(
|
||||
private val encryptionDetector: EncryptionDetector,
|
||||
) : EncryptionExtractor {
|
||||
|
||||
override fun extractEncryption(message: Message): EncryptionResult? {
|
||||
return if (encryptionDetector.isEncrypted(message)) {
|
||||
EncryptionResult(ENCRYPTION_TYPE, 0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ENCRYPTION_TYPE = "openpgp"
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(): OpenPgpEncryptionExtractor {
|
||||
val textPartFinder = TextPartFinder()
|
||||
val encryptionDetector = EncryptionDetector(textPartFinder)
|
||||
return OpenPgpEncryptionExtractor(encryptionDetector)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package com.fsck.k9.crypto.openpgp;
|
||||
|
||||
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.message.extractors.TextPartFinder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createMessage;
|
||||
import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createMultipartMessage;
|
||||
import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createPart;
|
||||
import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createTextMessage;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class EncryptionDetectorTest {
|
||||
private static final String CRLF = "\r\n";
|
||||
|
||||
|
||||
private EncryptionDetector encryptionDetector;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
encryptionDetector = new EncryptionDetector(new TextPartFinder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withTextPlain_shouldReturnFalse() {
|
||||
Message message = createTextMessage("text/plain", "plain text");
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertFalse(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withMultipartEncrypted_shouldReturnTrue() throws Exception {
|
||||
Message message = createMultipartMessage("multipart/encrypted",
|
||||
createPart("application/octet-stream"), createPart("application/octet-stream"));
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertTrue(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withSMimePart_shouldReturnTrue() {
|
||||
Message message = createMessage("application/pkcs7-mime");
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertTrue(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withMultipartMixedContainingSMimePart_shouldReturnTrue() throws Exception {
|
||||
Message message = createMultipartMessage("multipart/mixed",
|
||||
createPart("application/pkcs7-mime"), createPart("text/plain"));
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertTrue(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withInlinePgp_shouldReturnTrue() {
|
||||
Message message = createTextMessage("text/plain", "" +
|
||||
"-----BEGIN PGP MESSAGE-----" + CRLF +
|
||||
"some encrypted stuff here" + CRLF +
|
||||
"-----END PGP MESSAGE-----");
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertTrue(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withPlainTextAndPreambleWithInlinePgp_shouldReturnFalse() {
|
||||
Message message = createTextMessage("text/plain", "" +
|
||||
"preamble" + CRLF +
|
||||
"-----BEGIN PGP MESSAGE-----" + CRLF +
|
||||
"some encrypted stuff here" + CRLF +
|
||||
"-----END PGP MESSAGE-----" + CRLF +
|
||||
"epilogue");
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertFalse(encrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEncrypted_withQuotedInlinePgp_shouldReturnFalse() {
|
||||
Message message = createTextMessage("text/plain", "" +
|
||||
"good talk!" + CRLF +
|
||||
CRLF +
|
||||
"> -----BEGIN PGP MESSAGE-----" + CRLF +
|
||||
"> some encrypted stuff here" + CRLF +
|
||||
"> -----END PGP MESSAGE-----" + CRLF +
|
||||
CRLF +
|
||||
"-- " + CRLF +
|
||||
"my signature");
|
||||
|
||||
boolean encrypted = encryptionDetector.isEncrypted(message);
|
||||
|
||||
assertFalse(encrypted);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.fsck.k9.crypto.openpgp;
|
||||
|
||||
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import net.thunderbird.core.common.exception.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeHeader;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||
import com.fsck.k9.mail.internet.TextBody;
|
||||
import com.fsck.k9.mailstore.BinaryMemoryBody;
|
||||
|
||||
|
||||
public class MessageCreationHelper {
|
||||
public static BodyPart createPart(String mimeType) throws MessagingException {
|
||||
BinaryMemoryBody body = new BinaryMemoryBody(new byte[0], "utf-8");
|
||||
return new MimeBodyPart(body, mimeType);
|
||||
}
|
||||
|
||||
public static Message createTextMessage(String mimeType, String text) {
|
||||
TextBody body = new TextBody(text);
|
||||
return createMessage(mimeType, body);
|
||||
}
|
||||
|
||||
public static Message createMultipartMessage(String mimeType, BodyPart... parts) {
|
||||
MimeMultipart body = createMultipartBody(mimeType, parts);
|
||||
return createMessage(mimeType, body);
|
||||
}
|
||||
|
||||
public static Message createMessage(String mimeType) {
|
||||
return createMessage(mimeType, null);
|
||||
}
|
||||
|
||||
private static Message createMessage(String mimeType, Body body) {
|
||||
MimeMessage message = new MimeMessage();
|
||||
message.setBody(body);
|
||||
message.setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private static MimeMultipart createMultipartBody(String mimeType, BodyPart[] parts) {
|
||||
MimeMultipart multipart = new MimeMultipart(mimeType, "boundary");
|
||||
for (BodyPart part : parts) {
|
||||
multipart.addBodyPart(part);
|
||||
}
|
||||
return multipart;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue