Refactoring

pull/214/head
M66B 2 years ago
parent 311af85c5a
commit 71af2781cc

@ -1,17 +1,24 @@
package eu.faircode.email;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
public class SSLHelper {
static X509TrustManager getTrustManager(X509TrustManager rtm,
String server,
boolean secure, boolean cert_strict,
String trustedFingerprint,
ITrust intf) {
// https://support.google.com/faqs/answer/6346016
return null;
// https://support.google.com/faqs/answer/6346016
static TrustManager[] getTrustManagers(String server, boolean secure, boolean cert_strict, String trustedFingerprint, ITrust intf) {
TrustManagerFactory tmf;
try {
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
return tmf.getTrustManagers();
} catch (Throwable ex) {
Log.e(ex);
return null;
}
}
static boolean customTrustManager() {

@ -6,22 +6,45 @@ import androidx.annotation.NonNull;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.Principal;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class SSLHelper {
static X509TrustManager getTrustManager(X509TrustManager rtm,
String server,
boolean secure, boolean cert_strict,
String trustedFingerprint,
ITrust intf) {
return new X509TrustManager() {
static TrustManager[] getTrustManagers(String server, boolean secure, boolean cert_strict, String trustedFingerprint, ITrust intf) {
TrustManagerFactory tmf;
try {
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
} catch (Throwable ex) {
Log.e(ex);
tmf = null;
}
TrustManager[] tms = (tmf == null ? null : tmf.getTrustManagers());
Log.i("Trust managers=" + (tms == null ? null : tms.length));
if (tms == null || tms.length == 0 || !(tms[0] instanceof X509TrustManager)) {
Log.e("Missing root trust manager");
return tms;
}
if (tms.length > 1)
for (TrustManager tm : tms)
Log.e("Trust manager " + tm.getClass());
final X509TrustManager rtm = (X509TrustManager) tms[0];
return new TrustManager[]{new X509TrustManager() {
// openssl s_client -connect <host>
@Override
@ -105,9 +128,7 @@ public class SSLHelper {
private boolean noAnchor(Throwable ex) {
while (ex != null) {
if (ex instanceof CertPathValidatorException &&
"Trust anchor for certification path not found."
.equals(ex.getMessage()))
if (ex instanceof CertPathValidatorException)
return true;
ex = ex.getCause();
}
@ -116,16 +137,13 @@ public class SSLHelper {
private boolean isExpired(Throwable ex) {
while (ex != null) {
if (ex instanceof CertPathValidatorException &&
"timestamp check failed"
.equals(ex.getMessage()))
if (ex instanceof CertificateExpiredException)
return true;
ex = ex.getCause();
}
return false;
}
};
}};
}
static boolean customTrustManager() {

@ -1047,6 +1047,32 @@ public class EmailService implements AutoCloseable {
this.cert_strict = cert_strict;
this.trustedFingerprint = fingerprint;
TrustManager[] tms = SSLHelper.getTrustManagers(server, secure, cert_strict, trustedFingerprint,
new SSLHelper.ITrust() {
@Override
public void checkServerTrusted(X509Certificate[] chain) {
certificate = chain[0];
}
});
KeyManager[] km = null;
if (key != null && chain != null)
try {
Log.i("Client certificate init");
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, new char[0]);
ks.setKeyEntry(server, key, new char[0], chain);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, new char[0]);
km = kmf.getKeyManagers();
Log.i("Client certificate initialized");
} catch (Throwable ex) {
Log.e(ex);
}
// https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext
// https://stackoverflow.com/questions/69571364/sslcontext-getinstancetls-vulnerability
// https://developer.android.com/about/versions/oreo/android-8.0-changes.html#security-all
@ -1057,50 +1083,7 @@ public class EmailService implements AutoCloseable {
else
sslContext = SSLContext.getInstance(protocol);
Log.i("Using protocol=" + protocol + " bc=" + bc + " FIPS=" + fips);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
TrustManager[] tms = tmf.getTrustManagers();
Log.i("Trust managers=" + (tms == null ? null : tms.length));
if (tms == null || tms.length == 0 || !(tms[0] instanceof X509TrustManager)) {
Log.e("Missing root trust manager");
sslContext.init(null, tms, null);
} else {
final X509TrustManager rtm = (X509TrustManager) tms[0];
if (tms.length > 1)
for (TrustManager tm : tms)
Log.e("Trust manager " + tm.getClass());
X509TrustManager tm = SSLHelper.getTrustManager(rtm, server, secure, cert_strict, trustedFingerprint,
new SSLHelper.ITrust() {
@Override
public void checkServerTrusted(X509Certificate[] chain) {
certificate = chain[0];
}
});
KeyManager[] km = null;
if (key != null && chain != null)
try {
Log.i("Client certificate init");
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, new char[0]);
ks.setKeyEntry(server, key, new char[0], chain);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, new char[0]);
km = kmf.getKeyManagers();
Log.i("Client certificate initialized");
} catch (Throwable ex) {
Log.e(ex);
}
sslContext.init(km, new TrustManager[]{tm == null ? rtm : tm}, null);
}
sslContext.init(km, tms, null);
factory = sslContext.getSocketFactory();
}

Loading…
Cancel
Save