diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 4f3ffd4895..14eeb7c1c9 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -2335,6 +2335,9 @@ public class FragmentCompose extends FragmentBase { int type = args.getInt("type"); String alias = args.getString("alias"); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean check_certificate = prefs.getBoolean("check_certificate", true); + DB db = DB.getInstance(context); // Get data @@ -2378,24 +2381,47 @@ public class FragmentCompose extends FragmentBase { }; bpContent.setContent(imessage.getContent(), imessage.getContentType()); - // Store selected alias if (alias == null) throw new IllegalArgumentException("Key alias missing"); - db.identity().setIdentitySignKeyAlias(identity.id, alias); // Get private key PrivateKey privkey = KeyChain.getPrivateKey(context, alias); if (privkey == null) throw new IllegalArgumentException("Private key missing"); + + // Get public key X509Certificate[] chain = KeyChain.getCertificateChain(context, alias); if (chain == null || chain.length == 0) throw new IllegalArgumentException("Certificate missing"); - try { - chain[0].checkValidity(); - } catch (CertificateException ex) { - throw new IllegalArgumentException(context.getString(R.string.title_invalid_key), ex); + + if (check_certificate) { + // Check public key validity + try { + chain[0].checkValidity(); + } catch (CertificateException ex) { + throw new IllegalArgumentException(context.getString(R.string.title_invalid_key), ex); + } + + // Check public key email + boolean known = false; + List emails = EntityCertificate.getEmailAddresses(chain[0]); + for (String email : emails) + if (email.equals(identity.email)) { + known = true; + break; + } + + if (!known && emails.size() > 0) { + String message = identity.email + " (" + TextUtils.join(", ", emails) + ")"; + throw new IllegalArgumentException( + context.getString(R.string.title_certificate_missing, message), + new CertificateException()); + } } + // Store selected alias + db.identity().setIdentitySignKeyAlias(identity.id, alias); + // Build content if (EntityMessage.SMIME_SIGNONLY.equals(type)) { EntityAttachment cattachment = new EntityAttachment(); diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsEncryption.java b/app/src/main/java/eu/faircode/email/FragmentOptionsEncryption.java index 5ebe41c5d3..8bb355aab5 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsEncryption.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsEncryption.java @@ -74,6 +74,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre private SwitchCompat swAutocrypt; private SwitchCompat swAutocryptMutual; + private SwitchCompat swCheckCertificate; private Button btnManageCertificates; private Button btnImportKey; private Button btnManageKeys; @@ -85,7 +86,8 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre private final static String[] RESET_OPTIONS = new String[]{ "sign_default", "encrypt_default", "auto_decrypt", - "openpgp_provider", "autocrypt", "autocrypt_mutual" + "openpgp_provider", "autocrypt", "autocrypt_mutual", + "check_certificate" }; @Override @@ -107,6 +109,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre swAutocrypt = view.findViewById(R.id.swAutocrypt); swAutocryptMutual = view.findViewById(R.id.swAutocryptMutual); + swCheckCertificate = view.findViewById(R.id.swCheckCertificate); btnManageCertificates = view.findViewById(R.id.btnManageCertificates); btnImportKey = view.findViewById(R.id.btnImportKey); btnManageKeys = view.findViewById(R.id.btnManageKeys); @@ -190,6 +193,13 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre // S/MIME + swCheckCertificate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("check_certificate", checked).apply(); + } + }); + btnManageCertificates.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -343,6 +353,8 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre swAutocrypt.setChecked(prefs.getBoolean("autocrypt", true)); swAutocryptMutual.setChecked(prefs.getBoolean("autocrypt_mutual", true)); swAutocryptMutual.setEnabled(swAutocrypt.isChecked()); + + swCheckCertificate.setChecked(prefs.getBoolean("check_certificate", true)); } private void testOpenPgp(String pkg) { diff --git a/app/src/main/res/layout/fragment_options_encryption.xml b/app/src/main/res/layout/fragment_options_encryption.xml index fe0c5bcdc7..8f116e50d3 100644 --- a/app/src/main/res/layout/fragment_options_encryption.xml +++ b/app/src/main/res/layout/fragment_options_encryption.xml @@ -135,6 +135,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/swAutocryptMutual" /> + +