From 0f9f1b4ec60ae5ad7834cb9fec15a4dccec3827b Mon Sep 17 00:00:00 2001 From: M66B Date: Wed, 25 Dec 2019 11:23:25 +0100 Subject: [PATCH] Added Autocrypt mutual mode support --- .../eu/faircode/email/FragmentMessages.java | 42 ++++++++++++++----- .../email/FragmentOptionsPrivacy.java | 12 +++++- .../java/eu/faircode/email/MessageHelper.java | 9 +++- .../res/layout/fragment_options_privacy.xml | 14 ++++++- app/src/main/res/values/strings.xml | 1 + 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index a55ead18a7..d949d4c34e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -4288,19 +4288,39 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(data.getAction())) try { String peer = ((InternetAddress) message.from[0]).getAddress(); + boolean mutual = false; + byte[] keydata = null; - int k = message.autocrypt.indexOf("keydata="); - if (k >= 0) { - String keydata = message.autocrypt.substring(k + 8); - AutocryptPeerUpdate update = AutocryptPeerUpdate.create( - Base64.decode(keydata, Base64.DEFAULT), - new Date(message.received), - true); - - data.putExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_ID, peer); - data.putExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_UPDATE, update); + // https://autocrypt.org/level1.html#the-autocrypt-header + String[] param = message.autocrypt.split(";"); + for (int i = 0; i < param.length; i++) { + int e = param[i].indexOf("="); + if (e > 0) { + String key = param[i].substring(0, e).trim().toLowerCase(); + String value = param[i].substring(e + 1); + Log.i("Autocrypt " + key + "=" + value); + switch (key) { + case "addr": + break; + case "prefer-encrypt": + mutual = value.trim().toLowerCase().equals("mutual"); + break; + case "keydata": + keydata = Base64.decode(value, Base64.DEFAULT); + break; + } + } } - } catch (IllegalArgumentException ex) { + + if (keydata == null) + throw new IllegalArgumentException("keydata not found"); + + AutocryptPeerUpdate update = AutocryptPeerUpdate.create( + keydata, new Date(message.received), mutual); + + data.putExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_ID, peer); + data.putExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_UPDATE, update); + } catch (Throwable ex) { Log.w(ex); } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java b/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java index 542f57edcd..9d35d1be41 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java @@ -67,6 +67,7 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer private SwitchCompat swDisplayHidden; private Spinner spEncryptMethod; private Spinner spOpenPgp; + private SwitchCompat swAutocryptMutual; private SwitchCompat swSign; private SwitchCompat swEncrypt; private SwitchCompat swAutoDecrypt; @@ -83,7 +84,7 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer private final static String[] RESET_OPTIONS = new String[]{ "disable_tracking", "display_hidden", - "default_encrypt_method", "openpgp_provider", "sign_default", "encrypt_default", "auto_decrypt", + "default_encrypt_method", "openpgp_provider", "autocrypt_mutual", "sign_default", "encrypt_default", "auto_decrypt", "secure", "biometrics", "pin", "biometrics_timeout" }; @@ -103,6 +104,7 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer swDisplayHidden = view.findViewById(R.id.swDisplayHidden); spEncryptMethod = view.findViewById(R.id.spEncryptMethod); spOpenPgp = view.findViewById(R.id.spOpenPgp); + swAutocryptMutual = view.findViewById(R.id.swAutocryptMutual); swSign = view.findViewById(R.id.swSign); swEncrypt = view.findViewById(R.id.swEncrypt); swAutoDecrypt = view.findViewById(R.id.swAutoDecrypt); @@ -173,6 +175,13 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer } }); + swAutocryptMutual.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autocrypt_mutual", checked).apply(); + } + }); + swSign.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { @@ -347,6 +356,7 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer break; } + swAutocryptMutual.setChecked(prefs.getBoolean("autocrypt_mutual", true)); swSign.setChecked(prefs.getBoolean("sign_default", false)); swEncrypt.setChecked(prefs.getBoolean("encrypt_default", false)); swSign.setEnabled(!swEncrypt.isChecked()); diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 325210d552..8670b400bc 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -20,10 +20,13 @@ package eu.faircode.email; */ import android.content.Context; +import android.content.SharedPreferences; import android.net.MailTo; import android.net.Uri; import android.text.TextUtils; +import androidx.preference.PreferenceManager; + import com.sun.mail.util.FolderClosedIOException; import com.sun.mail.util.MessageRemovedIOException; @@ -233,6 +236,10 @@ public class MessageHelper { if (EntityAttachment.PGP_KEY.equals(attachment.encryption)) { InternetAddress from = (InternetAddress) message.from[0]; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean mutual = prefs.getBoolean("autocrypt_mutual", true); + String mode = (mutual ? "mutual" : "nopreference"); + StringBuilder sb = new StringBuilder(); File file = attachment.getFile(context); try (BufferedReader br = new BufferedReader(new FileReader(file))) { @@ -256,7 +263,7 @@ public class MessageHelper { // https://autocrypt.org/level1.html#the-autocrypt-header imessage.addHeader("Autocrypt", "addr=" + from.getAddress() + ";" + - " prefer-encrypt=mutual;" + + " prefer-encrypt=" + mode + ";" + " keydata=" + sb.toString()); } diff --git a/app/src/main/res/layout/fragment_options_privacy.xml b/app/src/main/res/layout/fragment_options_privacy.xml index b467b08673..eb77f18e29 100644 --- a/app/src/main/res/layout/fragment_options_privacy.xml +++ b/app/src/main/res/layout/fragment_options_privacy.xml @@ -102,6 +102,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvOpenPgp" /> + + Display hidden message texts Default encryption method OpenPGP provider + Autocrypt mutual mode Sign by default Encrypt by default Automatically decrypt messages