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:
parent
de8da4dab4
commit
4bec165fdc
@ -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())) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user