1
0
Fork 0
mirror of https://github.com/M66B/FairEmail.git synced 2025-03-11 06:33:29 +00:00

Added option to check S/MIME key usage on sending

This commit is contained in:
M66B 2024-12-09 08:02:52 +01:00
parent 01ee00fceb
commit bb8676b6e0
4 changed files with 53 additions and 4 deletions

View file

@ -4388,6 +4388,7 @@ public class FragmentCompose extends FragmentBase {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean check_certificate = prefs.getBoolean("check_certificate", true);
boolean check_key_usage = prefs.getBoolean("check_key_usage", false);
File tmp = Helper.ensureExists(context, "encryption");
@ -4455,8 +4456,30 @@ public class FragmentCompose extends FragmentBase {
// Check public key validity
try {
chain[0].checkValidity();
// TODO: check digitalSignature/nonRepudiation key usage
// https://datatracker.ietf.org/doc/html/rfc3850#section-4.4.2
if (check_key_usage) {
// Signing Key: Key Usage: Digital Signature, Non-Repudiation
// Encrypting Key: Key Usage: Key Encipherment, Data Encipherment
boolean[] usage = chain[0].getKeyUsage();
if (usage != null && usage.length > 3) {
// https://datatracker.ietf.org/doc/html/rfc3280#section-4.2.1.3
// https://datatracker.ietf.org/doc/html/rfc3850#section-4.4.2
boolean digitalSignature = usage[0];
boolean keyEncipherment = usage[2];
if (EntityMessage.SMIME_SIGNONLY.equals(type)) {
if (!digitalSignature)
throw new IllegalAccessException("Invalid key usage:" +
" digitalSignature=" + digitalSignature);
} else if (EntityMessage.SMIME_SIGNENCRYPT.equals(type)) {
if (!digitalSignature || !keyEncipherment)
throw new IllegalAccessException("Invalid key usage:" +
" digitalSignature=" + digitalSignature +
" keyEncipherment=" + keyEncipherment);
}
}
}
} catch (CertificateException ex) {
String msg = ex.getMessage();
throw new IllegalArgumentException(

View file

@ -105,6 +105,7 @@ public class FragmentOptionsEncryption extends FragmentBase
private Spinner spSignAlgoSmime;
private Spinner spEncryptAlgoSmime;
private SwitchCompat swCheckCertificate;
private SwitchCompat swCheckKeyUsage;
private Button btnManageCertificates;
private Button btnImportKey;
private Button btnManageKeys;
@ -123,7 +124,7 @@ public class FragmentOptionsEncryption extends FragmentBase
"sign_default", "encrypt_default", "encrypt_auto", "encrypt_reply",
"auto_verify", "auto_decrypt", "auto_undecrypt",
"openpgp_provider", "autocrypt", "autocrypt_mutual", "encrypt_subject",
"sign_algo_smime", "encrypt_algo_smime", "check_certificate"
"sign_algo_smime", "encrypt_algo_smime", "check_certificate", "check_key_usage"
));
@Override
@ -159,6 +160,7 @@ public class FragmentOptionsEncryption extends FragmentBase
spSignAlgoSmime = view.findViewById(R.id.spSignAlgoSmime);
spEncryptAlgoSmime = view.findViewById(R.id.spEncryptAlgoSmime);
swCheckCertificate = view.findViewById(R.id.swCheckCertificate);
swCheckKeyUsage = view.findViewById(R.id.swCheckKeyUsage);
btnManageCertificates = view.findViewById(R.id.btnManageCertificates);
btnImportKey = view.findViewById(R.id.btnImportKey);
btnManageKeys = view.findViewById(R.id.btnManageKeys);
@ -395,6 +397,14 @@ public class FragmentOptionsEncryption extends FragmentBase
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("check_certificate", checked).apply();
swCheckKeyUsage.setEnabled(checked);
}
});
swCheckKeyUsage.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("check_key_usage", checked).apply();
}
});
@ -709,6 +719,8 @@ public class FragmentOptionsEncryption extends FragmentBase
}
swCheckCertificate.setChecked(prefs.getBoolean("check_certificate", true));
swCheckKeyUsage.setChecked(prefs.getBoolean("check_key_usage", false));
swCheckKeyUsage.setEnabled(swCheckCertificate.isChecked());
} catch (Throwable ex) {
Log.e(ex);
}

View file

@ -421,6 +421,19 @@
app:layout_constraintTop_toBottomOf="@id/tvAlgoHint"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swCheckKeyUsage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:checked="true"
android:text="@string/title_advanced_check_key_usage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swCheckCertificate"
app:switchPadding="12dp" />
<Button
android:id="@+id/btnManageCertificates"
style="?android:attr/buttonStyleSmall"
@ -431,7 +444,7 @@
android:drawablePadding="6dp"
android:text="@string/title_advanced_manage_certificates"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swCheckCertificate" />
app:layout_constraintTop_toBottomOf="@id/swCheckKeyUsage" />
<Button
android:id="@+id/btnImportKey"

View file

@ -869,6 +869,7 @@
The default algorithms SHA256 and AES128 are commonly supported.
</string>
<string name="title_advanced_check_certificate">Check public key on sending</string>
<string name="title_advanced_check_key_usage">Check key usage on sending</string>
<string name="title_advanced_manage_certificates">Manage public keys</string>
<string name="title_advanced_import_key">Import private key</string>
<string name="title_advanced_manage_keys">Manage private keys</string>