mirror of
https://github.com/moparisthebest/k-9
synced 2025-01-14 07:08:00 -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.MessagingException;
|
||||||
import com.fsck.k9.mail.Multipart;
|
import com.fsck.k9.mail.Multipart;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
|
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
|
|
||||||
|
|
||||||
public class MessageDecryptVerifier {
|
public class MessageDecryptVerifier {
|
||||||
@ -20,6 +22,8 @@ public class MessageDecryptVerifier {
|
|||||||
private static final String PROTOCOL_PARAMETER = "protocol";
|
private static final String PROTOCOL_PARAMETER = "protocol";
|
||||||
private static final String APPLICATION_PGP_ENCRYPTED = "application/pgp-encrypted";
|
private static final String APPLICATION_PGP_ENCRYPTED = "application/pgp-encrypted";
|
||||||
private static final String APPLICATION_PGP_SIGNATURE = "application/pgp-signature";
|
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) {
|
public static List<Part> findEncryptedParts(Part startPart) {
|
||||||
List<Part> encryptedParts = new ArrayList<Part>();
|
List<Part> encryptedParts = new ArrayList<Part>();
|
||||||
@ -69,6 +73,35 @@ public class MessageDecryptVerifier {
|
|||||||
return signedParts;
|
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 {
|
public static byte[] getSignatureData(Part part) throws IOException, MessagingException {
|
||||||
|
|
||||||
if (MULTIPART_SIGNED.equals(part.getMimeType())) {
|
if (MULTIPART_SIGNED.equals(part.getMimeType())) {
|
||||||
|
@ -9,13 +9,13 @@ import org.openintents.openpgp.OpenPgpError;
|
|||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
|
|
||||||
|
|
||||||
public class OpenPgpResultBodyPart extends MimeBodyPart {
|
public class OpenPgpResultAnnotation extends MimeBodyPart {
|
||||||
private boolean wasEncrypted;
|
private boolean wasEncrypted;
|
||||||
private OpenPgpSignatureResult signatureResult;
|
private OpenPgpSignatureResult signatureResult;
|
||||||
private OpenPgpError error;
|
private OpenPgpError error;
|
||||||
private PendingIntent pendingIntent;
|
private PendingIntent pendingIntent;
|
||||||
|
|
||||||
public OpenPgpResultBodyPart(boolean wasEncrypted) throws MessagingException {
|
public OpenPgpResultAnnotation(boolean wasEncrypted) throws MessagingException {
|
||||||
this.wasEncrypted = wasEncrypted;
|
this.wasEncrypted = wasEncrypted;
|
||||||
}
|
}
|
||||||
|
|
@ -29,6 +29,7 @@ import com.fsck.k9.mail.BodyPart;
|
|||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Multipart;
|
import com.fsck.k9.mail.Multipart;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
|
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||||
import com.fsck.k9.mailstore.DecryptStreamParser;
|
import com.fsck.k9.mailstore.DecryptStreamParser;
|
||||||
import com.fsck.k9.mailstore.LocalMessage;
|
import com.fsck.k9.mailstore.LocalMessage;
|
||||||
import com.fsck.k9.mailstore.OpenPgpResultBodyPart;
|
import com.fsck.k9.mailstore.OpenPgpResultBodyPart;
|
||||||
@ -66,10 +67,12 @@ class MessageCryptoHelper {
|
|||||||
|
|
||||||
List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message);
|
List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message);
|
||||||
List<Part> signedParts = MessageDecryptVerifier.findSignedParts(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 = new ArrayDeque<Part>();
|
||||||
partsToDecryptOrVerify.addAll(encryptedParts);
|
partsToDecryptOrVerify.addAll(encryptedParts);
|
||||||
partsToDecryptOrVerify.addAll(signedParts);
|
partsToDecryptOrVerify.addAll(signedParts);
|
||||||
|
partsToDecryptOrVerify.addAll(inlineParts);
|
||||||
decryptOrVerifyNextPartOrStartExtractingTextAndAttachments();
|
decryptOrVerifyNextPartOrStartExtractingTextAndAttachments();
|
||||||
} else {
|
} else {
|
||||||
returnResultToFragment();
|
returnResultToFragment();
|
||||||
@ -80,7 +83,14 @@ class MessageCryptoHelper {
|
|||||||
if (!partsToDecryptOrVerify.isEmpty()) {
|
if (!partsToDecryptOrVerify.isEmpty()) {
|
||||||
|
|
||||||
Part part = partsToDecryptOrVerify.peekFirst();
|
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);
|
startDecryptingOrVerifyingPart(part);
|
||||||
} else {
|
} else {
|
||||||
partsToDecryptOrVerify.removeFirst();
|
partsToDecryptOrVerify.removeFirst();
|
||||||
@ -95,11 +105,6 @@ class MessageCryptoHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startDecryptingOrVerifyingPart(Part part) {
|
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()) {
|
if (!isBoundToCryptoProviderService()) {
|
||||||
connectToCryptoProviderService();
|
connectToCryptoProviderService();
|
||||||
} else {
|
} else {
|
||||||
@ -156,7 +161,7 @@ class MessageCryptoHelper {
|
|||||||
|
|
||||||
private void callAsyncDecrypt(Intent intent) throws IOException {
|
private void callAsyncDecrypt(Intent intent) throws IOException {
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedData();
|
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedOrInlineData();
|
||||||
PipedOutputStream decryptedOutputStream = getPipedOutputStreamForDecryptedData(latch);
|
PipedOutputStream decryptedOutputStream = getPipedOutputStreamForDecryptedData(latch);
|
||||||
|
|
||||||
openPgpApi.executeApiAsync(intent, pipedInputStream, decryptedOutputStream, new IOpenPgpCallback() {
|
openPgpApi.executeApiAsync(intent, pipedInputStream, decryptedOutputStream, new IOpenPgpCallback() {
|
||||||
@ -210,7 +215,7 @@ class MessageCryptoHelper {
|
|||||||
return pipedInputStream;
|
return pipedInputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PipedInputStream getPipedInputStreamForEncryptedData() throws IOException {
|
private PipedInputStream getPipedInputStreamForEncryptedOrInlineData() throws IOException {
|
||||||
PipedInputStream pipedInputStream = new PipedInputStream();
|
PipedInputStream pipedInputStream = new PipedInputStream();
|
||||||
|
|
||||||
final PipedOutputStream out = new PipedOutputStream(pipedInputStream);
|
final PipedOutputStream out = new PipedOutputStream(pipedInputStream);
|
||||||
@ -218,10 +223,16 @@ class MessageCryptoHelper {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Multipart multipartEncryptedMultipart = (Multipart) currentlyDecrypringOrVerifyingPart.getBody();
|
if (currentlyDecrypringOrVerifyingPart instanceof Multipart) {
|
||||||
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
|
Multipart multipartEncryptedMultipart =
|
||||||
Body encryptionPayloadBody = encryptionPayloadPart.getBody();
|
(Multipart) currentlyDecrypringOrVerifyingPart.getBody();
|
||||||
encryptionPayloadBody.writeTo(out);
|
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) {
|
} catch (Exception e) {
|
||||||
Log.e(K9.LOG_TAG, "Exception while writing message to crypto provider", e);
|
Log.e(K9.LOG_TAG, "Exception while writing message to crypto provider", e);
|
||||||
} finally {
|
} finally {
|
||||||
@ -345,6 +356,10 @@ class MessageCryptoHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addOpenPgpResultPartToMessage(OpenPgpResultBodyPart decryptedPart) {
|
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 multipart = (Multipart) currentlyDecrypringOrVerifyingPart.getBody();
|
||||||
multipart.addBodyPart(decryptedPart);
|
multipart.addBodyPart(decryptedPart);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user