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);
}