diff --git a/app/src/main/java/eu/faircode/email/ConnectionHelper.java b/app/src/main/java/eu/faircode/email/ConnectionHelper.java index 02aac597ab..56ce77e95f 100644 --- a/app/src/main/java/eu/faircode/email/ConnectionHelper.java +++ b/app/src/main/java/eu/faircode/email/ConnectionHelper.java @@ -29,6 +29,7 @@ import android.net.NetworkInfo; import android.os.Build; import android.provider.Settings; import android.telephony.TelephonyManager; +import android.text.TextUtils; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; @@ -36,8 +37,14 @@ import androidx.preference.PreferenceManager; import com.sun.mail.iap.ConnectionException; import com.sun.mail.util.FolderClosedIOException; +import org.bouncycastle.asn1.x509.GeneralName; + import java.io.IOException; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -455,4 +462,47 @@ public class ConnectionHelper { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0; } + + static List getDnsNames(X509Certificate certificate) throws CertificateParsingException { + List result = new ArrayList<>(); + + Collection> altNames = certificate.getSubjectAlternativeNames(); + if (altNames == null) + return result; + + for (List altName : altNames) + if (altName.get(0).equals(GeneralName.dNSName)) + result.add((String) altName.get(1)); + + return result; + } + + static boolean matches(String server, List names) { + for (String name : names) + if (matches(server, name)) { + Log.i("Trusted server=" + server + " name=" + name); + return true; + } + return false; + } + + private static boolean matches(String server, String name) { + if (name.startsWith("*.")) { + // Wildcard certificate + String domain = name.substring(2); + if (TextUtils.isEmpty(domain)) + return false; + + int dot = server.indexOf("."); + if (dot < 0) + return false; + + String cdomain = server.substring(dot + 1); + if (TextUtils.isEmpty(cdomain)) + return false; + + return domain.equalsIgnoreCase(cdomain); + } else + return server.equalsIgnoreCase(name); + } } diff --git a/app/src/main/java/eu/faircode/email/EmailService.java b/app/src/main/java/eu/faircode/email/EmailService.java index 8424f9bd63..1e2869d87c 100644 --- a/app/src/main/java/eu/faircode/email/EmailService.java +++ b/app/src/main/java/eu/faircode/email/EmailService.java @@ -38,7 +38,6 @@ import com.sun.mail.util.SocketConnectException; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import java.io.ByteArrayOutputStream; @@ -60,11 +59,9 @@ import java.security.Principal; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; -import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -835,12 +832,9 @@ public class EmailService implements AutoCloseable { } // Check host name - List names = getDnsNames(certificate); - for (String name : names) - if (matches(server, name)) { - Log.i("Trusted server=" + server + " name=" + name); - return; - } + List names = ConnectionHelper.getDnsNames(certificate); + if (ConnectionHelper.matches(server, names)) + return; String error = server + " not in certificate: " + TextUtils.join(",", names); Log.i(error); @@ -970,40 +964,6 @@ public class EmailService implements AutoCloseable { return factory.getSupportedCipherSuites(); } - private static boolean matches(String server, String name) { - if (name.startsWith("*.")) { - // Wildcard certificate - String domain = name.substring(2); - if (TextUtils.isEmpty(domain)) - return false; - - int dot = server.indexOf("."); - if (dot < 0) - return false; - - String cdomain = server.substring(dot + 1); - if (TextUtils.isEmpty(cdomain)) - return false; - - return domain.equalsIgnoreCase(cdomain); - } else - return server.equalsIgnoreCase(name); - } - - private static List getDnsNames(X509Certificate certificate) throws CertificateParsingException { - List result = new ArrayList<>(); - - Collection> altNames = certificate.getSubjectAlternativeNames(); - if (altNames == null) - return result; - - for (List altName : altNames) - if (altName.get(0).equals(GeneralName.dNSName)) - result.add((String) altName.get(1)); - - return result; - } - private static boolean matches(X509Certificate certificate, @NonNull String trustedFingerprint) { // Get certificate fingerprint try {