aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian.schneppe@pix-art.de>2019-12-08 15:40:58 +0100
committerChristian Schneppe <christian.schneppe@pix-art.de>2019-12-08 15:40:58 +0100
commit31c16b0f8fb54c26e45cdee9a4b47cfe4e5994fa (patch)
tree95a704f39d8adda949531263c51cf2ab73b3f31c
parent32b1ab2b3b54c53e61c61bc779ae01bc9b62c776 (diff)
delete cached posh file after not being able to verify
-rw-r--r--src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java93
1 files changed, 49 insertions, 44 deletions
diff --git a/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java b/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java
index 899a12d5b..f321332d7 100644
--- a/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java
+++ b/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java
@@ -34,11 +34,12 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.preference.PreferenceManager;
-import androidx.appcompat.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.util.SparseArray;
+import androidx.appcompat.app.AppCompatActivity;
+
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -104,12 +105,12 @@ public class MemorizingTrustManager {
private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
final static String DECISION_INTENT = "de.duenndns.ssl.DECISION";
- public final static String DECISION_INTENT_ID = DECISION_INTENT + ".decisionId";
- public final static String DECISION_INTENT_CERT = DECISION_INTENT + ".cert";
+ public final static String DECISION_INTENT_ID = DECISION_INTENT + ".decisionId";
+ public final static String DECISION_INTENT_CERT = DECISION_INTENT + ".cert";
final static String DECISION_INTENT_CHOICE = DECISION_INTENT + ".decisionChoice";
private final static Logger LOGGER = Logger.getLogger(MemorizingTrustManager.class.getName());
- public final static String DECISION_TITLE_ID = DECISION_INTENT + ".titleId";
+ public final static String DECISION_TITLE_ID = DECISION_INTENT + ".titleId";
private final static int NOTIFICATION_ID = 100509;
final static String NO_TRUST_ANCHOR = "Trust anchor for certification path not found.";
@@ -170,21 +171,22 @@ public class MemorizingTrustManager {
void init(Context m) {
master = m;
masterHandler = new Handler(m.getMainLooper());
- notificationManager = (NotificationManager)master.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager = (NotificationManager) master.getSystemService(Context.NOTIFICATION_SERVICE);
Application app;
if (m instanceof Application) {
- app = (Application)m;
+ app = (Application) m;
} else if (m instanceof Service) {
- app = ((Service)m).getApplication();
+ app = ((Service) m).getApplication();
} else if (m instanceof AppCompatActivity) {
- app = ((AppCompatActivity)m).getApplication();
- } else throw new ClassCastException("MemorizingTrustManager context must be either Activity or Service!");
+ app = ((AppCompatActivity) m).getApplication();
+ } else
+ throw new ClassCastException("MemorizingTrustManager context must be either Activity or Service!");
File dir = app.getDir(KEYSTORE_DIR, Context.MODE_PRIVATE);
keyStoreFile = new File(dir + File.separator + KEYSTORE_FILE);
- poshCacheDir = app.getFilesDir().getAbsolutePath()+"/posh_cache/";
+ poshCacheDir = app.getCacheDir().getAbsolutePath() + "/posh_cache/";
appKeyStore = loadAppKeyStore();
}
@@ -315,7 +317,7 @@ public class MemorizingTrustManager {
tmf.init(ks);
for (TrustManager t : tmf.getTrustManagers()) {
if (t instanceof X509TrustManager) {
- return (X509TrustManager)t;
+ return (X509TrustManager) t;
}
}
} catch (Exception e) {
@@ -401,8 +403,7 @@ public class MemorizingTrustManager {
}
public void checkCertTrusted(X509Certificate[] chain, String authType, String domain, boolean isServer, boolean interactive)
- throws CertificateException
- {
+ throws CertificateException {
LOGGER.log(Level.FINE, "checkCertTrusted(" + chain + ", " + authType + ", " + isServer + ")");
try {
LOGGER.log(Level.FINE, "checkCertTrusted: trying appTrustManager");
@@ -432,14 +433,18 @@ public class MemorizingTrustManager {
} catch (CertificateException e) {
boolean trustSystemCAs = !PreferenceManager.getDefaultSharedPreferences(master).getBoolean("dont_trust_system_cas", false);
if (domain != null && isServer && trustSystemCAs && !isIp(domain)) {
- String hash = getBase64Hash(chain[0],"SHA-256");
- List<String> fingerprints = getPoshFingerprints(domain);
- if (hash != null && fingerprints.contains(hash)) {
- Log.d("mtm","trusted cert fingerprint of "+domain+" via posh");
- return;
+ final String hash = getBase64Hash(chain[0], "SHA-256");
+ final List<String> fingerprints = getPoshFingerprints(domain);
+ if (hash != null && fingerprints.size() > 0) {
+ if (fingerprints.contains(hash)) {
+ Log.d("mtm", "trusted cert fingerprint of " + domain + " via posh");
+ return;
+ }
+ if (getPoshCacheFile(domain).delete()) {
+ Log.d("mtm", "deleted posh file for " + domain + " after not being able to verify");
+ }
}
}
- e.printStackTrace();
if (interactive) {
interactCert(chain, authType, e);
} else {
@@ -459,11 +464,11 @@ public class MemorizingTrustManager {
}
private List<String> getPoshFingerprintsFromServer(String domain) {
- return getPoshFingerprintsFromServer(domain, "https://"+domain+"/.well-known/posh/xmpp-client.json",-1,true);
+ return getPoshFingerprintsFromServer(domain, "https://" + domain + "/.well-known/posh/xmpp-client.json", -1, true);
}
private List<String> getPoshFingerprintsFromServer(String domain, String url, int maxTtl, boolean followUrl) {
- Log.d("mtm","downloading json for "+domain+" from "+url);
+ Log.d("mtm", "downloading json for " + domain + " from " + url);
try {
List<String> results = new ArrayList<>();
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
@@ -482,7 +487,7 @@ public class MemorizingTrustManager {
return new ArrayList<>();
}
if (maxTtl >= 0) {
- expires = Math.min(maxTtl,expires);
+ expires = Math.min(maxTtl, expires);
}
String redirect;
try {
@@ -494,23 +499,23 @@ public class MemorizingTrustManager {
return getPoshFingerprintsFromServer(domain, redirect, expires, false);
}
JSONArray fingerprints = jsonObject.getJSONArray("fingerprints");
- for(int i = 0; i < fingerprints.length(); i++) {
+ for (int i = 0; i < fingerprints.length(); i++) {
JSONObject fingerprint = fingerprints.getJSONObject(i);
String sha256 = fingerprint.getString("sha-256");
if (sha256 != null) {
results.add(sha256);
}
}
- writeFingerprintsToCache(domain, results,1000L * expires+System.currentTimeMillis());
+ writeFingerprintsToCache(domain, results, 1000L * expires + System.currentTimeMillis());
return results;
} catch (Exception e) {
- Log.d("mtm","error fetching posh "+e.getMessage());
+ Log.d("mtm", "error fetching posh " + e.getMessage());
return new ArrayList<>();
}
}
private File getPoshCacheFile(String domain) {
- return new File(poshCacheDir+domain+".json");
+ return new File(poshCacheDir + domain + ".json");
}
private void writeFingerprintsToCache(String domain, List<String> results, long expires) {
@@ -519,8 +524,8 @@ public class MemorizingTrustManager {
try {
file.createNewFile();
JSONObject jsonObject = new JSONObject();
- jsonObject.put("expires",expires);
- jsonObject.put("fingerprints",new JSONArray(results));
+ jsonObject.put("expires", expires);
+ jsonObject.put("fingerprints", new JSONArray(results));
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(jsonObject.toString().getBytes());
outputStream.flush();
@@ -539,7 +544,7 @@ public class MemorizingTrustManager {
String line = buf.readLine();
StringBuilder sb = new StringBuilder();
- while(line != null){
+ while (line != null) {
sb.append(line).append("\n");
line = buf.readLine();
}
@@ -551,11 +556,11 @@ public class MemorizingTrustManager {
file.delete();
return null;
} else {
- Log.d("mtm","posh fingerprints expire in "+(expiresIn/1000)+"s");
+ Log.d("mtm", "posh fingerprints expire in " + (expiresIn / 1000) + "s");
}
List<String> result = new ArrayList<>();
JSONArray jsonArray = jsonObject.getJSONArray("fingerprints");
- for(int i = 0; i < jsonArray.length(); ++i) {
+ for (int i = 0; i < jsonArray.length(); ++i) {
result.add(jsonArray.getString(i));
}
return result;
@@ -586,7 +591,7 @@ public class MemorizingTrustManager {
return null;
}
md.update(certificate.getEncoded());
- return Base64.encodeToString(md.digest(),Base64.NO_WRAP);
+ return Base64.encodeToString(md.digest(), Base64.NO_WRAP);
}
private X509Certificate[] getAcceptedIssuers() {
@@ -596,7 +601,7 @@ public class MemorizingTrustManager {
private int createDecisionId(MTMDecision d) {
int myId;
- synchronized(openDecisions) {
+ synchronized (openDecisions) {
myId = decisionId;
openDecisions.put(myId, d);
decisionId += 1;
@@ -681,7 +686,7 @@ public class MemorizingTrustManager {
Object name = altName.get(1);
if (name instanceof String) {
si.append("[");
- si.append((Integer)altName.get(0));
+ si.append((Integer) altName.get(0));
si.append("] ");
si.append(name);
si.append("\n");
@@ -735,7 +740,9 @@ public class MemorizingTrustManager {
LOGGER.log(Level.FINE, "openDecisions: " + openDecisions + ", waiting on " + myId);
try {
- synchronized(choice) { choice.wait(); }
+ synchronized (choice) {
+ choice.wait();
+ }
} catch (InterruptedException e) {
LOGGER.log(Level.FINER, "InterruptedException", e);
}
@@ -744,8 +751,7 @@ public class MemorizingTrustManager {
}
void interactCert(final X509Certificate[] chain, String authType, CertificateException cause)
- throws CertificateException
- {
+ throws CertificateException {
switch (interact(certChainMessage(chain, cause), R.string.mtm_accept_cert)) {
case MTMDecision.DECISION_ALWAYS:
storeCert(chain[0]); // only store the server cert, not the whole chain
@@ -756,8 +762,7 @@ public class MemorizingTrustManager {
}
}
- boolean interactHostname(X509Certificate cert, String hostname)
- {
+ boolean interactHostname(X509Certificate cert, String hostname) {
switch (interact(hostNameMessage(cert, hostname), R.string.mtm_accept_servername)) {
case MTMDecision.DECISION_ALWAYS:
storeCert(hostname, cert);
@@ -770,7 +775,7 @@ public class MemorizingTrustManager {
public static void interactResult(int decisionId, int choice) {
MTMDecision d;
- synchronized(openDecisions) {
+ synchronized (openDecisions) {
d = openDecisions.get(decisionId);
openDecisions.remove(decisionId);
}
@@ -778,7 +783,7 @@ public class MemorizingTrustManager {
LOGGER.log(Level.SEVERE, "interactResult: aborting due to stale decision reference!");
return;
}
- synchronized(d) {
+ synchronized (d) {
d.state = choice;
d.notify();
}
@@ -798,7 +803,7 @@ public class MemorizingTrustManager {
LOGGER.log(Level.FINE, "hostname verifier for " + domain + ", trying default verifier first");
// if the default verifier accepts the hostname, we are done
if (defaultVerifier instanceof DomainHostnameVerifier) {
- if (((DomainHostnameVerifier) defaultVerifier).verify(domain,hostname, session)) {
+ if (((DomainHostnameVerifier) defaultVerifier).verify(domain, hostname, session)) {
return true;
}
} else {
@@ -810,7 +815,7 @@ public class MemorizingTrustManager {
// otherwise, we check if the hostname is an alias for this cert in our keystore
try {
- X509Certificate cert = (X509Certificate)session.getPeerCertificates()[0];
+ X509Certificate cert = (X509Certificate) session.getPeerCertificates()[0];
//Log.d(TAG, "cert: " + cert);
if (cert.equals(appKeyStore.getCertificate(domain.toLowerCase(Locale.US)))) {
LOGGER.log(Level.FINE, "certificate for " + domain + " is in our keystore. accepting.");
@@ -831,7 +836,7 @@ public class MemorizingTrustManager {
@Override
public boolean verify(String domain, SSLSession sslSession) {
- return verify(domain,null,sslSession);
+ return verify(domain, null, sslSession);
}
}