|
|
@ -5556,9 +5556,10 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|
|
|
Log.w(ex);
|
|
|
|
Log.w(ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KeyStore ks = null;
|
|
|
|
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");
|
|
|
|
ks = KeyStore.getInstance("AndroidCAStore");
|
|
|
|
ks.load(null, null);
|
|
|
|
ks.load(null, null);
|
|
|
|
|
|
|
|
|
|
|
|
// https://docs.oracle.com/javase/7/docs/technotes/guides/security/certpath/CertPathProgGuide.html
|
|
|
|
// https://docs.oracle.com/javase/7/docs/technotes/guides/security/certpath/CertPathProgGuide.html
|
|
|
@ -5611,27 +5612,18 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|
|
|
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
|
|
|
|
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
|
|
|
|
cpv.validate(path.getCertPath(), params);
|
|
|
|
cpv.validate(path.getCertPath(), params);
|
|
|
|
|
|
|
|
|
|
|
|
List<Certificate> pcerts = new ArrayList<>();
|
|
|
|
List<X509Certificate> pcerts = new ArrayList<>();
|
|
|
|
pcerts.addAll(path.getCertPath().getCertificates());
|
|
|
|
pcerts.add(cert);
|
|
|
|
|
|
|
|
for (Certificate c : pcerts)
|
|
|
|
|
|
|
|
if (c instanceof X509Certificate)
|
|
|
|
|
|
|
|
pcerts.add((X509Certificate) c);
|
|
|
|
if (path instanceof PKIXCertPathValidatorResult) {
|
|
|
|
if (path instanceof PKIXCertPathValidatorResult) {
|
|
|
|
X509Certificate root = ((PKIXCertPathValidatorResult) path).getTrustAnchor().getTrustedCert();
|
|
|
|
X509Certificate root = ((PKIXCertPathValidatorResult) path).getTrustAnchor().getTrustedCert();
|
|
|
|
if (root != null)
|
|
|
|
if (root != null)
|
|
|
|
pcerts.add(root);
|
|
|
|
pcerts.add(root);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ArrayList<String> trace = new ArrayList<>();
|
|
|
|
args.putStringArrayList("trace", getTrace(pcerts, ks));
|
|
|
|
for (Certificate pcert : pcerts)
|
|
|
|
|
|
|
|
if (pcert instanceof X509Certificate) {
|
|
|
|
|
|
|
|
// https://tools.ietf.org/html/rfc5280#section-4.2.1.3
|
|
|
|
|
|
|
|
X509Certificate c = (X509Certificate) pcert;
|
|
|
|
|
|
|
|
boolean[] usage = c.getKeyUsage();
|
|
|
|
|
|
|
|
boolean root = (usage != null && usage[5]);
|
|
|
|
|
|
|
|
boolean selfSigned = c.getIssuerX500Principal().equals(c.getSubjectX500Principal());
|
|
|
|
|
|
|
|
EntityCertificate record = EntityCertificate.from(c, null);
|
|
|
|
|
|
|
|
trace.add((root ? "* " : "") + (selfSigned ? "# " : "") + record.subject);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
args.putStringArrayList("trace", trace);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean valid = true;
|
|
|
|
boolean valid = true;
|
|
|
|
for (Certificate pcert : pcerts)
|
|
|
|
for (Certificate pcert : pcerts)
|
|
|
@ -5647,16 +5639,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.w(ex);
|
|
|
|
Log.w(ex);
|
|
|
|
args.putString("reason", ex.getMessage());
|
|
|
|
args.putString("reason", ex.getMessage());
|
|
|
|
|
|
|
|
args.putStringArrayList("trace", getTrace(certs, ks));
|
|
|
|
ArrayList<String> trace = new ArrayList<>();
|
|
|
|
|
|
|
|
for (X509Certificate c : certs) {
|
|
|
|
|
|
|
|
boolean[] usage = c.getKeyUsage();
|
|
|
|
|
|
|
|
boolean root = (usage != null && usage[5]);
|
|
|
|
|
|
|
|
boolean selfSigned = c.getIssuerX500Principal().equals(c.getSubjectX500Principal());
|
|
|
|
|
|
|
|
EntityCertificate record = EntityCertificate.from(c, null);
|
|
|
|
|
|
|
|
trace.add((root ? "* " : "") + (selfSigned ? "# " : "") + record.subject);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
args.putStringArrayList("trace", trace);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = cert;
|
|
|
|
result = cert;
|
|
|
@ -5963,6 +5946,26 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|
|
|
WorkerFts.init(context, false);
|
|
|
|
WorkerFts.init(context, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ArrayList<String> getTrace(List<X509Certificate> certs, KeyStore ks) {
|
|
|
|
|
|
|
|
ArrayList<String> trace = new ArrayList<>();
|
|
|
|
|
|
|
|
for (Certificate c : certs)
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
X509Certificate cert = (X509Certificate) c;
|
|
|
|
|
|
|
|
boolean[] usage = cert.getKeyUsage();
|
|
|
|
|
|
|
|
boolean keyCertSign = (usage != null && usage[5]);
|
|
|
|
|
|
|
|
boolean selfSigned = cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal());
|
|
|
|
|
|
|
|
EntityCertificate record = EntityCertificate.from(cert, null);
|
|
|
|
|
|
|
|
trace.add(record.subject +
|
|
|
|
|
|
|
|
" (" + cert.getIssuerX500Principal() + ")" +
|
|
|
|
|
|
|
|
(keyCertSign ? " (keyCertSign)" : "") +
|
|
|
|
|
|
|
|
(selfSigned ? " (selfSigned)" : "") +
|
|
|
|
|
|
|
|
(ks != null && ks.getCertificateAlias(cert) != null ? " (Android)" : ""));
|
|
|
|
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
|
|
|
|
Log.e(ex);
|
|
|
|
|
|
|
|
trace.add(ex.toString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return trace;
|
|
|
|
|
|
|
|
}
|
|
|
|
}.execute(this, args, "decrypt:s/mime");
|
|
|
|
}.execute(this, args, "decrypt:s/mime");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|