port POSH code to OkHttp

This commit is contained in:
Daniel Gultsch 2021-03-22 14:32:31 +01:00
parent 70fc08314f
commit 8b90c1c498

View file

@ -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();