1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-13 14:48:04 -05:00

preliminary support for pgp/inline

This commit is contained in:
Vincent Breitmoser 2015-01-30 14:51:44 +01:00
parent de8da4dab4
commit 4bec165fdc
3 changed files with 63 additions and 15 deletions

View File

@ -12,6 +12,8 @@ import com.fsck.k9.mail.BodyPart;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MessageExtractor;
import org.openintents.openpgp.util.OpenPgpUtils;
public class MessageDecryptVerifier {
@ -20,6 +22,8 @@ public class MessageDecryptVerifier {
private static final String PROTOCOL_PARAMETER = "protocol";
private static final String APPLICATION_PGP_ENCRYPTED = "application/pgp-encrypted";
private static final String APPLICATION_PGP_SIGNATURE = "application/pgp-signature";
private static final String TEXT_PLAIN = "text/plain";
public static List<Part> findEncryptedParts(Part startPart) {
List<Part> encryptedParts = new ArrayList<Part>();
@ -69,6 +73,35 @@ public class MessageDecryptVerifier {
return signedParts;
}
public static List<Part> findPgpInlineParts(Part startPart) {
List<Part> inlineParts = new ArrayList<Part>();
Stack<Part> partsToCheck = new Stack<Part>();
partsToCheck.push(startPart);
while (!partsToCheck.isEmpty()) {
Part part = partsToCheck.pop();
String mimeType = part.getMimeType();
Body body = part.getBody();
if (TEXT_PLAIN.equals(mimeType)) {
String text = MessageExtractor.getTextFromPart(part);
switch (OpenPgpUtils.parseMessage(text)) {
case OpenPgpUtils.PARSE_RESULT_MESSAGE:
case OpenPgpUtils.PARSE_RESULT_SIGNED_MESSAGE:
inlineParts.add(part);
}
} else if (body instanceof Multipart) {
Multipart multipart = (Multipart) body;
for (int i = multipart.getCount() - 1; i >= 0; i--) {
BodyPart bodyPart = multipart.getBodyPart(i);
partsToCheck.push(bodyPart);
}
}
}
return inlineParts;
}
public static byte[] getSignatureData(Part part) throws IOException, MessagingException {
if (MULTIPART_SIGNED.equals(part.getMimeType())) {

View File

@ -9,13 +9,13 @@ import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
public class OpenPgpResultBodyPart extends MimeBodyPart {
public class OpenPgpResultAnnotation extends MimeBodyPart {
private boolean wasEncrypted;
private OpenPgpSignatureResult signatureResult;
private OpenPgpError error;
private PendingIntent pendingIntent;
public OpenPgpResultBodyPart(boolean wasEncrypted) throws MessagingException {
public OpenPgpResultAnnotation(boolean wasEncrypted) throws MessagingException {
this.wasEncrypted = wasEncrypted;
}

View File

@ -29,6 +29,7 @@ import com.fsck.k9.mail.BodyPart;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mailstore.DecryptStreamParser;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mailstore.OpenPgpResultBodyPart;
@ -66,10 +67,12 @@ class MessageCryptoHelper {
List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message);
List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message);
if (!encryptedParts.isEmpty() || !signedParts.isEmpty()) {
List<Part> inlineParts = MessageDecryptVerifier.findPgpInlineParts(message);
if (!encryptedParts.isEmpty() || !signedParts.isEmpty() || !inlineParts.isEmpty()) {
partsToDecryptOrVerify = new ArrayDeque<Part>();
partsToDecryptOrVerify.addAll(encryptedParts);
partsToDecryptOrVerify.addAll(signedParts);
partsToDecryptOrVerify.addAll(inlineParts);
decryptOrVerifyNextPartOrStartExtractingTextAndAttachments();
} else {
returnResultToFragment();
@ -80,7 +83,14 @@ class MessageCryptoHelper {
if (!partsToDecryptOrVerify.isEmpty()) {
Part part = partsToDecryptOrVerify.peekFirst();
if (MessageDecryptVerifier.isPgpMimePart(part)) {
if ("text/plain".equalsIgnoreCase(part.getMimeType())) {
startDecryptingOrVerifyingPart(part);
} else if (MessageDecryptVerifier.isPgpMimePart(part)) {
Multipart multipart = (Multipart) part.getBody();
if (multipart == null) {
throw new RuntimeException("Downloading missing parts before decryption isn't supported yet");
}
startDecryptingOrVerifyingPart(part);
} else {
partsToDecryptOrVerify.removeFirst();
@ -95,11 +105,6 @@ class MessageCryptoHelper {
}
private void startDecryptingOrVerifyingPart(Part part) {
Multipart multipart = (Multipart) part.getBody();
if (multipart == null) {
throw new RuntimeException("Downloading missing parts before decryption isn't supported yet");
}
if (!isBoundToCryptoProviderService()) {
connectToCryptoProviderService();
} else {
@ -156,7 +161,7 @@ class MessageCryptoHelper {
private void callAsyncDecrypt(Intent intent) throws IOException {
final CountDownLatch latch = new CountDownLatch(1);
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedData();
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedOrInlineData();
PipedOutputStream decryptedOutputStream = getPipedOutputStreamForDecryptedData(latch);
openPgpApi.executeApiAsync(intent, pipedInputStream, decryptedOutputStream, new IOpenPgpCallback() {
@ -210,7 +215,7 @@ class MessageCryptoHelper {
return pipedInputStream;
}
private PipedInputStream getPipedInputStreamForEncryptedData() throws IOException {
private PipedInputStream getPipedInputStreamForEncryptedOrInlineData() throws IOException {
PipedInputStream pipedInputStream = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(pipedInputStream);
@ -218,10 +223,16 @@ class MessageCryptoHelper {
@Override
public void run() {
try {
Multipart multipartEncryptedMultipart = (Multipart) currentlyDecrypringOrVerifyingPart.getBody();
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
Body encryptionPayloadBody = encryptionPayloadPart.getBody();
encryptionPayloadBody.writeTo(out);
if (currentlyDecrypringOrVerifyingPart instanceof Multipart) {
Multipart multipartEncryptedMultipart =
(Multipart) currentlyDecrypringOrVerifyingPart.getBody();
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
Body encryptionPayloadBody = encryptionPayloadPart.getBody();
encryptionPayloadBody.writeTo(out);
} else {
String text = MessageExtractor.getTextFromPart(currentlyDecrypringOrVerifyingPart);
out.write(text.getBytes());
}
} catch (Exception e) {
Log.e(K9.LOG_TAG, "Exception while writing message to crypto provider", e);
} finally {
@ -345,6 +356,10 @@ class MessageCryptoHelper {
}
private void addOpenPgpResultPartToMessage(OpenPgpResultBodyPart decryptedPart) {
if ( ! (currentlyDecrypringOrVerifyingPart.getBody() instanceof Multipart)) {
// TODO this is a text/plain part - care about this later!
return;
}
Multipart multipart = (Multipart) currentlyDecrypringOrVerifyingPart.getBody();
multipart.addBodyPart(decryptedPart);
}