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