diff --git a/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java b/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java index 1aa82d8a3..62fa053b1 100644 --- a/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java +++ b/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java @@ -31,6 +31,7 @@ import android.app.NotificationManager; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Handler; import android.preference.PreferenceManager; @@ -40,6 +41,9 @@ import android.util.SparseArray; import androidx.appcompat.app.AppCompatActivity; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -52,7 +56,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URL; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.MessageDigest; @@ -74,7 +77,6 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -83,6 +85,7 @@ import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.DomainHostnameVerifier; import eu.siacs.conversations.entities.MTMDecision; +import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.ui.MemorizingActivity; @@ -486,15 +489,18 @@ public class MemorizingTrustManager { defaultTrustManager.checkServerTrusted(chain, authType); else defaultTrustManager.checkClientTrusted(chain, authType); - } catch (CertificateException e) { - boolean trustSystemCAs = !PreferenceManager.getDefaultSharedPreferences(master).getBoolean("dont_trust_system_cas", false); - if (domain != null && isServer && trustSystemCAs && !isIp(domain)) { + } catch (final CertificateException e) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(master); + final boolean trustSystemCAs = !preferences.getBoolean("dont_trust_system_cas", false); + if (domain != null && isServer && trustSystemCAs && !isIp(domain) && !domain.endsWith(".onion")) { final String hash = getBase64Hash(chain[0], "SHA-256"); final List fingerprints = getPoshFingerprints(domain); if (hash != null && fingerprints.size() > 0) { if (fingerprints.contains(hash)) { Log.d("mtm", "trusted cert fingerprint of " + domain + " via posh"); return; + } else { + Log.d("mtm", "fingerprint " + hash + " not found in " + fingerprints); } if (getPoshCacheFile(domain).delete()) { Log.d("mtm", "deleted posh file for " + domain + " after not being able to verify"); @@ -511,7 +517,7 @@ public class MemorizingTrustManager { } private List getPoshFingerprints(String domain) { - List cached = getPoshFingerprintsFromCache(domain); + final List cached = getPoshFingerprintsFromCache(domain); if (cached == null) { return getPoshFingerprintsFromServer(domain); } else { @@ -525,19 +531,13 @@ public class MemorizingTrustManager { private List getPoshFingerprintsFromServer(String domain, String url, int maxTtl, boolean followUrl) { Log.d("mtm", "downloading json for " + domain + " from " + url); + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(master); + final boolean useTor = QuickConversationsService.isConversations() && preferences.getBoolean("use_tor", master.getResources().getBoolean(R.bool.use_tor)); try { - List results = new ArrayList<>(); - HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String inputLine; - StringBuilder builder = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - builder.append(inputLine); - } - JSONObject jsonObject = new JSONObject(builder.toString()); - in.close(); + final List results = new ArrayList<>(); + final InputStream inputStream = HttpConnectionManager.open(url, useTor); + final String body = CharStreams.toString(new InputStreamReader(inputStream, Charsets.UTF_8)); + final JSONObject jsonObject = new JSONObject(body); int expires = jsonObject.getInt("expires"); if (expires <= 0) { return new ArrayList<>(); @@ -554,17 +554,15 @@ public class MemorizingTrustManager { if (followUrl && redirect != null && redirect.toLowerCase().startsWith("https")) { return getPoshFingerprintsFromServer(domain, redirect, expires, false); } - JSONArray fingerprints = jsonObject.getJSONArray("fingerprints"); + final JSONArray fingerprints = jsonObject.getJSONArray("fingerprints"); 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); - } + final JSONObject fingerprint = fingerprints.getJSONObject(i); + final String sha256 = fingerprint.getString("sha-256"); + results.add(sha256); } writeFingerprintsToCache(domain, results, 1000L * expires + System.currentTimeMillis()); return results; - } catch (Exception e) { + } catch (final Exception e) { Log.d("mtm", "error fetching posh " + e.getMessage()); return new ArrayList<>(); } @@ -575,7 +573,7 @@ public class MemorizingTrustManager { } private void writeFingerprintsToCache(String domain, List results, long expires) { - File file = getPoshCacheFile(domain); + final File file = getPoshCacheFile(domain); file.getParentFile().mkdirs(); try { file.createNewFile();