1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-27 11:42:16 -05:00

Save type of crypto part for later use

This commit is contained in:
cketti 2015-02-21 01:35:36 +01:00
parent 6f3f555986
commit e5e4c29736
2 changed files with 83 additions and 56 deletions

View File

@ -120,16 +120,6 @@ public class MessageDecryptVerifier {
return null; return null;
} }
// Note: This method should ONLY be used to differentiate parts
// already filtered with the methods above!
public static boolean isPgpInlinePart(Part part) {
return TEXT_PLAIN.equals(part.getMimeType());
}
public static boolean isPgpMimePart(Part part) {
return isPgpMimeSignedPart(part) || isPgpMimeEncryptedPart(part);
}
public static boolean isPgpMimeSignedPart(Part part) { public static boolean isPgpMimeSignedPart(Part part) {
return MULTIPART_SIGNED.equals(part.getMimeType()); return MULTIPART_SIGNED.equals(part.getMimeType());
} }
@ -141,5 +131,4 @@ public class MessageDecryptVerifier {
// return APPLICATION_PGP_ENCRYPTED.equals(protocol); // return APPLICATION_PGP_ENCRYPTED.equals(protocol);
return MULTIPART_ENCRYPTED.equals(part.getMimeType()); return MULTIPART_ENCRYPTED.equals(part.getMimeType());
} }
} }

View File

@ -57,9 +57,9 @@ public class MessageCryptoHelper {
private final Account account; private final Account account;
private LocalMessage message; private LocalMessage message;
private Deque<Part> partsToDecryptOrVerify; private Deque<CryptoPart> partsToDecryptOrVerify = new ArrayDeque<CryptoPart>();
private OpenPgpApi openPgpApi; private OpenPgpApi openPgpApi;
private Part currentlyDecryptingOrVerifyingPart; private CryptoPart currentCryptoPart;
private Intent currentCryptoResult; private Intent currentCryptoResult;
private MessageCryptoAnnotations messageAnnotations; private MessageCryptoAnnotations messageAnnotations;
@ -83,16 +83,40 @@ public class MessageCryptoHelper {
} }
List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message); List<Part> encryptedParts = MessageDecryptVerifier.findEncryptedParts(message);
processFoundParts(encryptedParts, CryptoPartType.ENCRYPTED, CryptoError.ENCRYPTED_BUT_INCOMPLETE);
List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message);
processFoundParts(signedParts, CryptoPartType.SIGNED, CryptoError.SIGNED_BUT_INCOMPLETE);
List<Part> inlineParts = MessageDecryptVerifier.findPgpInlineParts(message); List<Part> inlineParts = MessageDecryptVerifier.findPgpInlineParts(message);
if (!encryptedParts.isEmpty() || !signedParts.isEmpty() || !inlineParts.isEmpty()) { addFoundInlinePgpParts(inlineParts);
partsToDecryptOrVerify = new ArrayDeque<Part>();
partsToDecryptOrVerify.addAll(encryptedParts);
partsToDecryptOrVerify.addAll(signedParts);
partsToDecryptOrVerify.addAll(inlineParts);
decryptOrVerifyNextPart(); decryptOrVerifyNextPart();
}
private void processFoundParts(List<Part> foundParts, CryptoPartType cryptoPartType,
CryptoError errorIfIncomplete) {
for (Part part : foundParts) {
if (MessageHelper.isCompletePartAvailable(part)) {
CryptoPart cryptoPart = new CryptoPart(cryptoPartType, part);
partsToDecryptOrVerify.add(cryptoPart);
} else { } else {
returnResultToFragment(); addErrorAnnotation(part, errorIfIncomplete);
}
}
}
private void addErrorAnnotation(Part part, CryptoError error) {
OpenPgpResultAnnotation annotation = new OpenPgpResultAnnotation();
annotation.setErrorType(error);
messageAnnotations.put(part, annotation);
}
private void addFoundInlinePgpParts(List<Part> foundParts) {
for (Part part : foundParts) {
CryptoPart cryptoPart = new CryptoPart(CryptoPartType.INLINE_PGP, part);
partsToDecryptOrVerify.add(cryptoPart);
} }
} }
@ -102,30 +126,15 @@ public class MessageCryptoHelper {
return; return;
} }
Part part = partsToDecryptOrVerify.peekFirst(); CryptoPart cryptoPart = partsToDecryptOrVerify.peekFirst();
if (!MessageHelper.isCompletePartAvailable(part)) { startDecryptingOrVerifyingPart(cryptoPart);
addErrorAnnotation(part);
} else {
startDecryptingOrVerifyingPart(part);
}
} }
private void addErrorAnnotation(Part part) { private void startDecryptingOrVerifyingPart(CryptoPart cryptoPart) {
OpenPgpResultAnnotation annotation = new OpenPgpResultAnnotation();
if (MessageDecryptVerifier.isPgpMimeSignedPart(part)) {
annotation.setErrorType(CryptoError.SIGNED_BUT_INCOMPLETE);
} else {
annotation.setErrorType(CryptoError.ENCRYPTED_BUT_INCOMPLETE);
}
messageAnnotations.put(part, annotation);
onCryptoFinished();
}
private void startDecryptingOrVerifyingPart(Part part) {
if (!isBoundToCryptoProviderService()) { if (!isBoundToCryptoProviderService()) {
connectToCryptoProviderService(); connectToCryptoProviderService();
} else { } else {
decryptOrVerifyPart(part); decryptOrVerifyPart(cryptoPart);
} }
} }
@ -151,8 +160,8 @@ public class MessageCryptoHelper {
}).bindToService(); }).bindToService();
} }
private void decryptOrVerifyPart(Part part) { private void decryptOrVerifyPart(CryptoPart cryptoPart) {
currentlyDecryptingOrVerifyingPart = part; currentCryptoPart = cryptoPart;
decryptVerify(new Intent()); decryptVerify(new Intent());
} }
@ -164,13 +173,23 @@ public class MessageCryptoHelper {
intent.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, accountName); intent.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, accountName);
try { try {
if (MessageDecryptVerifier.isPgpMimeSignedPart(currentlyDecryptingOrVerifyingPart)) { CryptoPartType cryptoPartType = currentCryptoPart.type;
switch (cryptoPartType) {
case SIGNED: {
callAsyncDetachedVerify(intent); callAsyncDetachedVerify(intent);
} else if (MessageDecryptVerifier.isPgpInlinePart(currentlyDecryptingOrVerifyingPart)) { return;
callAsyncInlineOperation(intent);
} else {
callAsyncDecrypt(intent);
} }
case ENCRYPTED: {
callAsyncDecrypt(intent);
return;
}
case INLINE_PGP: {
callAsyncInlineOperation(intent);
return;
}
}
throw new IllegalStateException("Unknown crypto part type: " + cryptoPartType);
} catch (IOException e) { } catch (IOException e) {
Log.e(K9.LOG_TAG, "IOException", e); Log.e(K9.LOG_TAG, "IOException", e);
} catch (MessagingException e) { } catch (MessagingException e) {
@ -217,7 +236,7 @@ public class MessageCryptoHelper {
private void callAsyncDetachedVerify(Intent intent) throws IOException, MessagingException { private void callAsyncDetachedVerify(Intent intent) throws IOException, MessagingException {
PipedInputStream pipedInputStream = getPipedInputStreamForSignedData(); PipedInputStream pipedInputStream = getPipedInputStreamForSignedData();
byte[] signatureData = MessageDecryptVerifier.getSignatureData(currentlyDecryptingOrVerifyingPart); byte[] signatureData = MessageDecryptVerifier.getSignatureData(currentCryptoPart.part);
intent.putExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE, signatureData); intent.putExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE, signatureData);
openPgpApi.executeApiAsync(intent, pipedInputStream, null, new IOpenPgpCallback() { openPgpApi.executeApiAsync(intent, pipedInputStream, null, new IOpenPgpCallback() {
@ -237,7 +256,7 @@ public class MessageCryptoHelper {
@Override @Override
public void run() { public void run() {
try { try {
Multipart multipartSignedMultipart = (Multipart) currentlyDecryptingOrVerifyingPart.getBody(); Multipart multipartSignedMultipart = (Multipart) currentCryptoPart.part.getBody();
BodyPart signatureBodyPart = multipartSignedMultipart.getBodyPart(0); BodyPart signatureBodyPart = multipartSignedMultipart.getBodyPart(0);
Log.d(K9.LOG_TAG, "signed data type: " + signatureBodyPart.getMimeType()); Log.d(K9.LOG_TAG, "signed data type: " + signatureBodyPart.getMimeType());
signatureBodyPart.writeTo(out); signatureBodyPart.writeTo(out);
@ -264,14 +283,15 @@ public class MessageCryptoHelper {
@Override @Override
public void run() { public void run() {
try { try {
if (MessageDecryptVerifier.isPgpMimePart(currentlyDecryptingOrVerifyingPart)) { Part part = currentCryptoPart.part;
Multipart multipartEncryptedMultipart = CryptoPartType cryptoPartType = currentCryptoPart.type;
(Multipart) currentlyDecryptingOrVerifyingPart.getBody(); if (cryptoPartType == CryptoPartType.ENCRYPTED) {
Multipart multipartEncryptedMultipart = (Multipart) part.getBody();
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1); BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
Body encryptionPayloadBody = encryptionPayloadPart.getBody(); Body encryptionPayloadBody = encryptionPayloadPart.getBody();
encryptionPayloadBody.writeTo(out); encryptionPayloadBody.writeTo(out);
} else if (MessageDecryptVerifier.isPgpInlinePart(currentlyDecryptingOrVerifyingPart)) { } else if (cryptoPartType == CryptoPartType.INLINE_PGP) {
String text = MessageExtractor.getTextFromPart(currentlyDecryptingOrVerifyingPart); String text = MessageExtractor.getTextFromPart(part);
out.write(text.getBytes()); out.write(text.getBytes());
} else { } else {
Log.wtf(K9.LOG_TAG, "No suitable data to stream found!"); Log.wtf(K9.LOG_TAG, "No suitable data to stream found!");
@ -417,7 +437,8 @@ public class MessageCryptoHelper {
} }
private void addOpenPgpResultPartToMessage(OpenPgpResultAnnotation resultAnnotation) { private void addOpenPgpResultPartToMessage(OpenPgpResultAnnotation resultAnnotation) {
messageAnnotations.put(currentlyDecryptingOrVerifyingPart, resultAnnotation); Part part = currentCryptoPart.part;
messageAnnotations.put(part, resultAnnotation);
} }
private void onCryptoFailed(OpenPgpError error) { private void onCryptoFailed(OpenPgpError error) {
@ -435,4 +456,21 @@ public class MessageCryptoHelper {
private void returnResultToFragment() { private void returnResultToFragment() {
callback.onCryptoOperationsFinished(messageAnnotations); callback.onCryptoOperationsFinished(messageAnnotations);
} }
private static class CryptoPart {
public final CryptoPartType type;
public final Part part;
CryptoPart(CryptoPartType type, Part part) {
this.type = type;
this.part = part;
}
}
private enum CryptoPartType {
INLINE_PGP,
ENCRYPTED,
SIGNED
}
} }