mirror of
https://github.com/M66B/FairEmail.git
synced 2025-02-24 15:11:03 +00:00
Refactoring
This commit is contained in:
parent
e013adf7f3
commit
77fce9735e
3 changed files with 86 additions and 59 deletions
|
@ -1,16 +1,23 @@
|
|||
package eu.faircode.email;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
public class SSLHelper {
|
||||
static X509TrustManager getTrustManager(X509TrustManager rtm,
|
||||
String server,
|
||||
boolean secure, boolean cert_strict,
|
||||
String trustedFingerprint,
|
||||
ITrust intf) {
|
||||
|
@ -53,6 +60,41 @@ public class SSLHelper {
|
|||
} else
|
||||
throw new CertificateException(principal.getName(), ex);
|
||||
}
|
||||
|
||||
// Check host name
|
||||
List<String> names = EntityCertificate.getDnsNames(chain[0]);
|
||||
if (EntityCertificate.matches(server, names))
|
||||
return;
|
||||
|
||||
// Fallback: check server/certificate IP address
|
||||
if (!cert_strict)
|
||||
try {
|
||||
InetAddress ip = InetAddress.getByName(server);
|
||||
Log.i("Checking server ip=" + ip);
|
||||
for (String name : names) {
|
||||
if (name.startsWith("*."))
|
||||
name = name.substring(2);
|
||||
Log.i("Checking cert name=" + name);
|
||||
|
||||
try {
|
||||
for (InetAddress addr : InetAddress.getAllByName(name))
|
||||
if (Arrays.equals(ip.getAddress(), addr.getAddress())) {
|
||||
Log.i("Accepted " + name + " for " + server);
|
||||
return;
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
||||
String error = server + " not in certificate: " + TextUtils.join(",", names);
|
||||
Log.i(error);
|
||||
throw new CertificateException(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
package eu.faircode.email;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
public class SSLHelper {
|
||||
static X509TrustManager getTrustManager(X509TrustManager rtm,
|
||||
String server,
|
||||
boolean secure, boolean cert_strict,
|
||||
String trustedFingerprint,
|
||||
ITrust intf) {
|
||||
|
@ -53,6 +60,41 @@ public class SSLHelper {
|
|||
} else
|
||||
throw new CertificateException(principal.getName(), ex);
|
||||
}
|
||||
|
||||
// Check host name
|
||||
List<String> names = EntityCertificate.getDnsNames(chain[0]);
|
||||
if (EntityCertificate.matches(server, names))
|
||||
return;
|
||||
|
||||
// Fallback: check server/certificate IP address
|
||||
if (!cert_strict)
|
||||
try {
|
||||
InetAddress ip = InetAddress.getByName(server);
|
||||
Log.i("Checking server ip=" + ip);
|
||||
for (String name : names) {
|
||||
if (name.startsWith("*."))
|
||||
name = name.substring(2);
|
||||
Log.i("Checking cert name=" + name);
|
||||
|
||||
try {
|
||||
for (InetAddress addr : InetAddress.getAllByName(name))
|
||||
if (Arrays.equals(ip.getAddress(), addr.getAddress())) {
|
||||
Log.i("Accepted " + name + " for " + server);
|
||||
return;
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
||||
String error = server + " not in certificate: " + TextUtils.join(",", names);
|
||||
Log.i(error);
|
||||
throw new CertificateException(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ import java.net.UnknownHostException;
|
|||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
|
@ -90,7 +89,6 @@ import javax.net.ssl.KeyManagerFactory;
|
|||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
@ -1076,7 +1074,7 @@ public class EmailService implements AutoCloseable {
|
|||
for (TrustManager tm : tms)
|
||||
Log.e("Trust manager " + tm.getClass());
|
||||
|
||||
X509TrustManager tm = SSLHelper.getTrustManager(rtm, secure, cert_strict, trustedFingerprint,
|
||||
X509TrustManager tm = SSLHelper.getTrustManager(rtm, server, secure, cert_strict, trustedFingerprint,
|
||||
new SSLHelper.ITrust() {
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain) {
|
||||
|
@ -1123,62 +1121,7 @@ public class EmailService implements AutoCloseable {
|
|||
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||
configureSocketOptions(s);
|
||||
ApplicationSecure.waitProviderInstalled();
|
||||
Socket socket = configure(factory.createSocket(s, server, port, autoClose));
|
||||
|
||||
if (!secure || !(socket instanceof SSLSocket))
|
||||
return socket;
|
||||
|
||||
List<String> names = new ArrayList<>();
|
||||
SSLSession session = ((SSLSocket) socket).getSession();
|
||||
Certificate[] certs = (session == null ? null : session.getPeerCertificates());
|
||||
if (certs != null && certs.length > 0 && certs[0] instanceof X509Certificate)
|
||||
try {
|
||||
names = EntityCertificate.getDnsNames((X509Certificate) certs[0]);
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
|
||||
Log.i("SSL session" +
|
||||
" server=" + server +
|
||||
" host=" + host + ":" + port +
|
||||
" host=" + session.getPeerHost() +
|
||||
" protocol=" + session.getProtocol() +
|
||||
" cipher=" + session.getCipherSuite() +
|
||||
" names=" + TextUtils.join(", ", names));
|
||||
|
||||
// Check host name
|
||||
if (EntityCertificate.matches(server, names))
|
||||
return socket;
|
||||
|
||||
// Fallback: check server/certificate IP address
|
||||
if (!cert_strict)
|
||||
try {
|
||||
InetAddress ip = InetAddress.getByName(server);
|
||||
Log.i("Checking server ip=" + ip);
|
||||
for (String name : names) {
|
||||
if (name.startsWith("*."))
|
||||
name = name.substring(2);
|
||||
Log.i("Checking cert name=" + name);
|
||||
|
||||
try {
|
||||
for (InetAddress addr : InetAddress.getAllByName(name))
|
||||
if (Arrays.equals(ip.getAddress(), addr.getAddress())) {
|
||||
Log.i("Accepted " + name + " for " + server);
|
||||
return socket;
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.w(ex);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
||||
String error = server + " not in certificate: " + TextUtils.join(",", names);
|
||||
Log.i(error);
|
||||
throw new ConnectException(error);
|
||||
return configure(factory.createSocket(s, server, port, autoClose));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue