port POSH code to OkHttp

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java | 50 
1 file changed, 24 insertions(+), 26 deletions(-)

Detailed changes

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<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;
+                        } 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<String> getPoshFingerprints(String domain) {
-        List<String> cached = getPoshFingerprintsFromCache(domain);
+        final List<String> cached = getPoshFingerprintsFromCache(domain);
         if (cached == null) {
             return getPoshFingerprintsFromServer(domain);
         } else {
@@ -525,19 +531,13 @@ public class MemorizingTrustManager {
 
     private List<String> 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<String> 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<String> 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<String> results, long expires) {
-        File file = getPoshCacheFile(domain);
+        final File file = getPoshCacheFile(domain);
         file.getParentFile().mkdirs();
         try {
             file.createNewFile();