messageview: handling for unsupported multipart/(signed|encrypted)
This commit is contained in:
parent
e71cff565e
commit
7305a20b8b
2 changed files with 70 additions and 38 deletions
|
@ -39,7 +39,7 @@ public class MessageDecryptVerifier {
|
|||
Part part = partsToCheck.pop();
|
||||
Body body = part.getBody();
|
||||
|
||||
if (isPgpMimeEncryptedPart(part)) {
|
||||
if (isPartMultipartEncrypted(part)) {
|
||||
encryptedParts.add(part);
|
||||
} else if (body instanceof Multipart) {
|
||||
Multipart multipart = (Multipart) body;
|
||||
|
@ -62,7 +62,7 @@ public class MessageDecryptVerifier {
|
|||
Part part = partsToCheck.pop();
|
||||
Body body = part.getBody();
|
||||
|
||||
if (isPgpMimeSignedPart(part)) {
|
||||
if (isPartMultipartSigned(part)) {
|
||||
signedParts.add(part);
|
||||
} else if (body instanceof Multipart) {
|
||||
Multipart multipart = (Multipart) body;
|
||||
|
@ -109,7 +109,7 @@ public class MessageDecryptVerifier {
|
|||
}
|
||||
|
||||
public static byte[] getSignatureData(Part part) throws IOException, MessagingException {
|
||||
if (isPgpMimeSignedPart(part)) {
|
||||
if (isPartMultipartSigned(part)) {
|
||||
Body body = part.getBody();
|
||||
if (body instanceof Multipart) {
|
||||
Multipart multi = (Multipart) body;
|
||||
|
@ -125,23 +125,23 @@ public class MessageDecryptVerifier {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static boolean isPgpMimeSignedPart(Part part) {
|
||||
if (!isSameMimeType(part.getMimeType(), MULTIPART_SIGNED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String contentType = part.getContentType();
|
||||
String protocol = MimeUtility.getHeaderParameter(contentType, PROTOCOL_PARAMETER);
|
||||
return APPLICATION_PGP_SIGNATURE.equalsIgnoreCase(protocol);
|
||||
private static boolean isPartMultipartSigned(Part part) {
|
||||
return isSameMimeType(part.getMimeType(), MULTIPART_SIGNED);
|
||||
}
|
||||
|
||||
private static boolean isPgpMimeEncryptedPart(Part part) {
|
||||
if (!isSameMimeType(part.getMimeType(), MULTIPART_ENCRYPTED)) {
|
||||
return false;
|
||||
}
|
||||
private static boolean isPartMultipartEncrypted(Part part) {
|
||||
return isSameMimeType(part.getMimeType(), MULTIPART_ENCRYPTED);
|
||||
}
|
||||
|
||||
public static boolean isPgpMimeEncryptedOrSignedPart(Part part) {
|
||||
String contentType = part.getContentType();
|
||||
String protocol = MimeUtility.getHeaderParameter(contentType, PROTOCOL_PARAMETER);
|
||||
return APPLICATION_PGP_ENCRYPTED.equalsIgnoreCase(protocol);
|
||||
String protocolParameter = MimeUtility.getHeaderParameter(contentType, PROTOCOL_PARAMETER);
|
||||
|
||||
boolean isPgpEncrypted = isSameMimeType(part.getMimeType(), MULTIPART_ENCRYPTED) &&
|
||||
APPLICATION_PGP_ENCRYPTED.equalsIgnoreCase(protocolParameter);
|
||||
boolean isPgpSigned = isSameMimeType(part.getMimeType(), MULTIPART_SIGNED) &&
|
||||
APPLICATION_PGP_SIGNATURE.equalsIgnoreCase(protocolParameter);
|
||||
|
||||
return isPgpEncrypted || isPgpSigned;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
|
@ -29,6 +30,7 @@ import com.fsck.k9.mail.Multipart;
|
|||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||
import com.fsck.k9.mail.internet.TextBody;
|
||||
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
||||
import com.fsck.k9.mailstore.DecryptStreamParser;
|
||||
|
@ -55,7 +57,6 @@ public class MessageCryptoHelper {
|
|||
private final Activity activity;
|
||||
private final MessageCryptoCallback callback;
|
||||
private final Account account;
|
||||
private LocalMessage message;
|
||||
|
||||
private Deque<CryptoPart> partsToDecryptOrVerify = new ArrayDeque<>();
|
||||
private OpenPgpApi openPgpApi;
|
||||
|
@ -76,19 +77,17 @@ public class MessageCryptoHelper {
|
|||
}
|
||||
|
||||
public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) {
|
||||
this.message = message;
|
||||
|
||||
if (!account.isOpenPgpProviderConfigured()) {
|
||||
returnResultToFragment();
|
||||
return;
|
||||
}
|
||||
|
||||
List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message);
|
||||
processFoundParts(encryptedParts, CryptoPartType.ENCRYPTED, CryptoError.ENCRYPTED_BUT_INCOMPLETE,
|
||||
processFoundEncryptedParts(encryptedParts,
|
||||
MessageHelper.createEmptyPart());
|
||||
|
||||
List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message);
|
||||
processFoundParts(signedParts, CryptoPartType.SIGNED, CryptoError.SIGNED_BUT_INCOMPLETE, NO_REPLACEMENT_PART);
|
||||
processFoundSignedParts(signedParts);
|
||||
|
||||
List<Part> inlineParts = MessageDecryptVerifier.findPgpInlineParts(message);
|
||||
addFoundInlinePgpParts(inlineParts);
|
||||
|
@ -96,15 +95,35 @@ public class MessageCryptoHelper {
|
|||
decryptOrVerifyNextPart();
|
||||
}
|
||||
|
||||
private void processFoundParts(List<Part> foundParts, CryptoPartType cryptoPartType, CryptoError errorIfIncomplete,
|
||||
MimeBodyPart replacementPart) {
|
||||
private void processFoundEncryptedParts(List<Part> foundParts, MimeBodyPart replacementPart) {
|
||||
for (Part part : foundParts) {
|
||||
if (MessageHelper.isCompletePartAvailable(part)) {
|
||||
CryptoPart cryptoPart = new CryptoPart(cryptoPartType, part);
|
||||
partsToDecryptOrVerify.add(cryptoPart);
|
||||
} else {
|
||||
addErrorAnnotation(part, errorIfIncomplete, replacementPart);
|
||||
if (!MessageHelper.isCompletePartAvailable(part)) {
|
||||
addErrorAnnotation(part, CryptoError.ENCRYPTED_BUT_INCOMPLETE, replacementPart);
|
||||
continue;
|
||||
}
|
||||
if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) {
|
||||
CryptoPart cryptoPart = new CryptoPart(CryptoPartType.PGP_ENCRYPTED, part);
|
||||
partsToDecryptOrVerify.add(cryptoPart);
|
||||
continue;
|
||||
}
|
||||
addErrorAnnotation(part, CryptoError.ENCRYPTED_BUT_UNSUPPORTED, replacementPart);
|
||||
}
|
||||
}
|
||||
|
||||
private void processFoundSignedParts(List<Part> foundParts) {
|
||||
for (Part part : foundParts) {
|
||||
if (!MessageHelper.isCompletePartAvailable(part)) {
|
||||
MimeBodyPart replacementPart = getMultipartSignedContentPartIfAvailable(part);
|
||||
addErrorAnnotation(part, CryptoError.SIGNED_BUT_INCOMPLETE, replacementPart);
|
||||
continue;
|
||||
}
|
||||
if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) {
|
||||
CryptoPart cryptoPart = new CryptoPart(CryptoPartType.PGP_SIGNED, part);
|
||||
partsToDecryptOrVerify.add(cryptoPart);
|
||||
continue;
|
||||
}
|
||||
MimeBodyPart replacementPart = getMultipartSignedContentPartIfAvailable(part);
|
||||
addErrorAnnotation(part, CryptoError.SIGNED_BUT_UNSUPPORTED, replacementPart);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +134,7 @@ public class MessageCryptoHelper {
|
|||
|
||||
private void addFoundInlinePgpParts(List<Part> foundParts) {
|
||||
for (Part part : foundParts) {
|
||||
CryptoPart cryptoPart = new CryptoPart(CryptoPartType.INLINE_PGP, part);
|
||||
CryptoPart cryptoPart = new CryptoPart(CryptoPartType.PGP_INLINE, part);
|
||||
partsToDecryptOrVerify.add(cryptoPart);
|
||||
}
|
||||
}
|
||||
|
@ -176,15 +195,15 @@ public class MessageCryptoHelper {
|
|||
try {
|
||||
CryptoPartType cryptoPartType = currentCryptoPart.type;
|
||||
switch (cryptoPartType) {
|
||||
case SIGNED: {
|
||||
case PGP_SIGNED: {
|
||||
callAsyncDetachedVerify(intent);
|
||||
return;
|
||||
}
|
||||
case ENCRYPTED: {
|
||||
case PGP_ENCRYPTED: {
|
||||
callAsyncDecrypt(intent);
|
||||
return;
|
||||
}
|
||||
case INLINE_PGP: {
|
||||
case PGP_INLINE: {
|
||||
callAsyncInlineOperation(intent);
|
||||
return;
|
||||
}
|
||||
|
@ -286,12 +305,12 @@ public class MessageCryptoHelper {
|
|||
try {
|
||||
Part part = currentCryptoPart.part;
|
||||
CryptoPartType cryptoPartType = currentCryptoPart.type;
|
||||
if (cryptoPartType == CryptoPartType.ENCRYPTED) {
|
||||
if (cryptoPartType == CryptoPartType.PGP_ENCRYPTED) {
|
||||
Multipart multipartEncryptedMultipart = (Multipart) part.getBody();
|
||||
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
|
||||
Body encryptionPayloadBody = encryptionPayloadPart.getBody();
|
||||
encryptionPayloadBody.writeTo(out);
|
||||
} else if (cryptoPartType == CryptoPartType.INLINE_PGP) {
|
||||
} else if (cryptoPartType == CryptoPartType.PGP_INLINE) {
|
||||
String text = MessageExtractor.getTextFromPart(part);
|
||||
out.write(text.getBytes());
|
||||
} else {
|
||||
|
@ -464,8 +483,21 @@ public class MessageCryptoHelper {
|
|||
}
|
||||
|
||||
private enum CryptoPartType {
|
||||
INLINE_PGP,
|
||||
ENCRYPTED,
|
||||
SIGNED
|
||||
PGP_INLINE,
|
||||
PGP_ENCRYPTED,
|
||||
PGP_SIGNED
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MimeBodyPart getMultipartSignedContentPartIfAvailable(Part part) {
|
||||
MimeBodyPart replacementPart = NO_REPLACEMENT_PART;
|
||||
Body body = part.getBody();
|
||||
if (body instanceof MimeMultipart) {
|
||||
MimeMultipart multipart = ((MimeMultipart) part.getBody());
|
||||
if (multipart.getCount() >= 1) {
|
||||
replacementPart = (MimeBodyPart) multipart.getBodyPart(0);
|
||||
}
|
||||
}
|
||||
return replacementPart;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue