Optional show S/MIME certificates

This commit is contained in:
M66B 2020-01-28 18:27:58 +01:00
parent 9911e1f8c8
commit 33b842bce5
1 changed files with 50 additions and 8 deletions

View File

@ -154,8 +154,11 @@ import java.nio.charset.StandardCharsets;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertPathValidator;
import java.security.cert.CertStore; import java.security.cert.CertStore;
import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreParameters;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters; import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXBuilderParameters;
@ -4787,6 +4790,16 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
args.putString("sender", sender); args.putString("sender", sender);
args.putBoolean("known", known); args.putBoolean("known", known);
List<X509Certificate> certs = new ArrayList<>();
try {
for (Object m : store.getMatches(null)) {
X509CertificateHolder h = (X509CertificateHolder) m;
certs.add(new JcaX509CertificateConverter().getCertificate(h));
}
} catch (Throwable ex) {
Log.w(ex);
}
try { try {
// https://tools.ietf.org/html/rfc3852#section-10.2.3 // https://tools.ietf.org/html/rfc3852#section-10.2.3
KeyStore ks = KeyStore.getInstance("AndroidCAStore"); KeyStore ks = KeyStore.getInstance("AndroidCAStore");
@ -4795,12 +4808,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
X509CertSelector target = new X509CertSelector(); X509CertSelector target = new X509CertSelector();
target.setCertificate(cert); target.setCertificate(cert);
List<X509Certificate> certs = new ArrayList<>();
for (Object m : store.getMatches(null)) {
X509CertificateHolder h = (X509CertificateHolder) m;
certs.add(new JcaX509CertificateConverter().getCertificate(h));
}
PKIXBuilderParameters params = new PKIXBuilderParameters(ks, target); PKIXBuilderParameters params = new PKIXBuilderParameters(ks, target);
CertStoreParameters intermediates = new CollectionCertStoreParameters(certs); CertStoreParameters intermediates = new CollectionCertStoreParameters(certs);
params.addCertStore(CertStore.getInstance("Collection", intermediates)); params.addCertStore(CertStore.getInstance("Collection", intermediates));
@ -4808,11 +4815,29 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
params.setDate(new Date(message.received)); params.setDate(new Date(message.received));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
builder.build(params); CertPathBuilderResult path = builder.build(params);
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
cpv.validate(path.getCertPath(), params);
args.putBoolean("valid", true); args.putBoolean("valid", true);
ArrayList<String> trace = new ArrayList<>();
for (Certificate c : path.getCertPath().getCertificates())
if (c instanceof X509Certificate) {
EntityCertificate record = EntityCertificate.from((X509Certificate) c, null);
trace.add(record.subject);
}
args.putStringArrayList("trace", trace);
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);
ArrayList<String> trace = new ArrayList<>();
for (X509Certificate c : certs) {
EntityCertificate record = EntityCertificate.from(c, null);
trace.add(record.subject);
}
args.putStringArrayList("trace", trace);
} }
result = cert; result = cert;
@ -4952,6 +4977,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
String sender = args.getString("sender"); String sender = args.getString("sender");
boolean known = args.getBoolean("known"); boolean known = args.getBoolean("known");
boolean valid = args.getBoolean("valid"); boolean valid = args.getBoolean("valid");
final ArrayList<String> trace = args.getStringArrayList("trace");
if (cert == null) if (cert == null)
Snackbar.make(view, R.string.title_signature_invalid, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_signature_invalid, Snackbar.LENGTH_LONG).show();
@ -4992,6 +5018,23 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
tvBefore.setText(record.before == null ? null : TF.format(record.before)); tvBefore.setText(record.before == null ? null : TF.format(record.before));
tvExpired.setVisibility(record.isExpired() ? View.VISIBLE : View.GONE); tvExpired.setVisibility(record.isExpired() ? View.VISIBLE : View.GONE);
if (trace != null && trace.size() > 0)
tvSubject.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < trace.size(); i++) {
if (i > 0)
sb.append("\n\n");
sb.append(i + 1).append(") ").append(trace.get(i));
}
new AlertDialog.Builder(getContext())
.setMessage(sb.toString())
.show();
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
.setView(dview) .setView(dview)
.setNegativeButton(android.R.string.cancel, null); .setNegativeButton(android.R.string.cancel, null);
@ -5019,7 +5062,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
String fingerprint = EntityCertificate.getFingerprint(cert); String fingerprint = EntityCertificate.getFingerprint(cert);
List<String> emails = EntityCertificate.getAltSubjectName(cert); List<String> emails = EntityCertificate.getAltSubjectName(cert);
String subject = EntityCertificate.getSubject(cert);
for (String email : emails) { for (String email : emails) {
EntityCertificate record = db.certificate().getCertificate(fingerprint, email); EntityCertificate record = db.certificate().getCertificate(fingerprint, email);
if (record == null) { if (record == null) {