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:
parent
6f3f555986
commit
e5e4c29736
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user