From 99dea3a466e2f6544e4a21341aad36f81ae2f22f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 28 Jun 2017 15:41:33 +0200 Subject: [PATCH] import keys from autocrypt headers --- .../fsck/k9/crypto/AutocryptOperations.java | 9 +-- .../fsck/k9/message/PgpMessageBuilder.java | 3 +- .../k9/ui/crypto/MessageCryptoHelper.java | 56 ++++++++++++++++--- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/crypto/AutocryptOperations.java b/k9mail/src/main/java/com/fsck/k9/crypto/AutocryptOperations.java index e0412b90a..57f907d64 100644 --- a/k9mail/src/main/java/com/fsck/k9/crypto/AutocryptOperations.java +++ b/k9mail/src/main/java/com/fsck/k9/crypto/AutocryptOperations.java @@ -11,6 +11,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; +import com.fsck.k9.mail.Message; import com.fsck.k9.mail.internet.MimeMessage; import com.fsck.k9.mail.internet.MimeUtility; import okio.ByteString; @@ -30,7 +31,7 @@ public class AutocryptOperations { } - private boolean addAutocryptPeerUpdateToIntentIfPresent(MimeMessage currentMessage, Intent intent) { + public boolean addAutocryptPeerUpdateToIntentIfPresent(Message currentMessage, Intent intent) { AutocryptHeader autocryptHeader = getValidAutocryptHeader(currentMessage); if (autocryptHeader == null) { return false; @@ -51,7 +52,7 @@ public class AutocryptOperations { return true; } - public void processCleartextMessage(OpenPgpApi openPgpApi, MimeMessage currentMessage) { + public void processCleartextMessage(OpenPgpApi openPgpApi, Message currentMessage) { Intent intent = new Intent(OpenPgpApi.ACTION_UPDATE_AUTOCRYPT_PEER); boolean hasInlineKeyData = addAutocryptPeerUpdateToIntentIfPresent(currentMessage, intent); if (hasInlineKeyData) { @@ -61,7 +62,7 @@ public class AutocryptOperations { @Nullable @VisibleForTesting - AutocryptHeader getValidAutocryptHeader(MimeMessage currentMessage) { + AutocryptHeader getValidAutocryptHeader(Message currentMessage) { String[] headers = currentMessage.getHeader(AUTOCRYPT_HEADER); ArrayList autocryptHeaders = parseAllAutocryptHeaders(headers); @@ -126,7 +127,7 @@ public class AutocryptOperations { return false; } - public boolean hasAutocryptHeader(MimeMessage currentMessage) { + public boolean hasAutocryptHeader(Message currentMessage) { return currentMessage.getHeader(AUTOCRYPT_HEADER).length > 0; } diff --git a/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java b/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java index 8f4254a5a..20e84ff8c 100644 --- a/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java +++ b/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java @@ -11,10 +11,8 @@ import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; -import timber.log.Timber; import com.fsck.k9.Globals; -import com.fsck.k9.K9; import com.fsck.k9.activity.compose.ComposeCryptoStatus; import com.fsck.k9.mail.Body; import com.fsck.k9.mail.BodyPart; @@ -36,6 +34,7 @@ import org.apache.james.mime4j.util.MimeUtil; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource; +import timber.log.Timber; public class PgpMessageBuilder extends MessageBuilder { diff --git a/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java b/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java index 59550fd95..7b58fc79a 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java @@ -17,6 +17,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; +import com.fsck.k9.crypto.AutocryptOperations; +import timber.log.Timber; + import com.fsck.k9.K9; import com.fsck.k9.crypto.MessageDecryptVerifier; import com.fsck.k9.mail.Address; @@ -62,6 +65,7 @@ public class MessageCryptoHelper { private final Context context; private final String openPgpProviderPackage; + private final AutocryptOperations autocryptOperations; private final Object callbackLock = new Object(); private final Deque partsToDecryptOrVerify = new ArrayDeque<>(); @@ -79,6 +83,7 @@ public class MessageCryptoHelper { private Intent currentCryptoResult; private Intent userInteractionResultIntent; private boolean secondPassStarted; + private boolean thirdPassStarted; private CancelableBackgroundOperation cancelableBackgroundOperation; private boolean isCancelled; @@ -95,6 +100,7 @@ public class MessageCryptoHelper { } this.openPgpApiFactory = openPgpApiFactory; + autocryptOperations = new AutocryptOperations(); openPgpProviderPackage = K9.getOpenPgpProvider(); } @@ -125,6 +131,8 @@ public class MessageCryptoHelper { } private void runSecondPass() { + secondPassStarted = true; + List signedParts = MessageDecryptVerifier.findSignedParts(currentMessage, messageAnnotations); processFoundSignedParts(signedParts); @@ -134,6 +142,19 @@ public class MessageCryptoHelper { decryptOrVerifyNextPart(); } + private void runThirdPass() { + thirdPassStarted = true; + + if (messageAnnotations.isEmpty()) { + if (autocryptOperations.hasAutocryptHeader(currentMessage)) { + CryptoPart cryptoPart = new CryptoPart(CryptoPartType.PLAIN_AUTOCRYPT, currentMessage); + partsToDecryptOrVerify.add(cryptoPart); + } + } + + decryptOrVerifyNextPart(); + } + private void processFoundEncryptedParts(List foundParts) { for (Part part : foundParts) { if (!MessageHelper.isCompletePartAvailable(part)) { @@ -194,7 +215,7 @@ public class MessageCryptoHelper { } if (partsToDecryptOrVerify.isEmpty()) { - runSecondPassOrReturnResultToFragment(); + runNextPassOrReturnResultToFragment(); return; } @@ -239,19 +260,22 @@ public class MessageCryptoHelper { Intent decryptIntent = userInteractionResultIntent; userInteractionResultIntent = null; if (decryptIntent == null) { - decryptIntent = getDecryptionIntent(); + decryptIntent = getDecryptVerifyIntent(); } decryptVerify(decryptIntent); } @NonNull - private Intent getDecryptionIntent() { + private Intent getDecryptVerifyIntent() { Intent decryptIntent = new Intent(OpenPgpApi.ACTION_DECRYPT_VERIFY); Address[] from = currentMessage.getFrom(); if (from.length > 0) { decryptIntent.putExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS, from[0].getAddress()); + // we add this here independently of the autocrypt peer update, to allow picking up signing keys as gossip + decryptIntent.putExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_ID, from[0].getAddress()); } + autocryptOperations.addAutocryptPeerUpdateToIntentIfPresent(currentMessage, decryptIntent); decryptIntent.putExtra(OpenPgpApi.EXTRA_SUPPORT_OVERRIDE_CRYPTO_WARNING, true); decryptIntent.putExtra(OpenPgpApi.EXTRA_DECRYPTION_RESULT, cachedDecryptionResult); @@ -275,6 +299,10 @@ public class MessageCryptoHelper { callAsyncInlineOperation(intent); return; } + case PLAIN_AUTOCRYPT: { + callAsyncParseAutocryptHeaderOperation(); + return; + } } throw new IllegalStateException("Unknown crypto part type: " + cryptoPartType); @@ -285,6 +313,12 @@ public class MessageCryptoHelper { } } + private void callAsyncParseAutocryptHeaderOperation() { + // TODO make actually async (then callback to onCryptoFinished) + autocryptOperations.processCleartextMessage(openPgpApi, (Message) currentCryptoPart.part); + onCryptoFinished(); + } + private void callAsyncInlineOperation(Intent intent) throws IOException { OpenPgpDataSource dataSource = getDataSourceForEncryptedOrInlineData(); OpenPgpDataSink dataSink = getDataSinkForDecryptedInlineData(); @@ -600,13 +634,16 @@ public class MessageCryptoHelper { decryptOrVerifyNextPart(); } - private void runSecondPassOrReturnResultToFragment() { - if (secondPassStarted) { - callbackReturnResult(); + private void runNextPassOrReturnResultToFragment() { + if (!secondPassStarted) { + runSecondPass(); return; } - secondPassStarted = true; - runSecondPass(); + if (!thirdPassStarted) { + runThirdPass(); + return; + } + callbackReturnResult(); } private void cleanupAfterProcessingFinished() { @@ -699,7 +736,8 @@ public class MessageCryptoHelper { private enum CryptoPartType { PGP_INLINE, PGP_ENCRYPTED, - PGP_SIGNED + PGP_SIGNED, + PLAIN_AUTOCRYPT } @Nullable