|
|
@ -9,6 +9,7 @@ import android.content.Intent; |
|
|
|
import android.graphics.Bitmap; |
|
|
|
import android.graphics.Bitmap; |
|
|
|
import android.net.MailTo; |
|
|
|
import android.net.MailTo; |
|
|
|
import android.net.Uri; |
|
|
|
import android.net.Uri; |
|
|
|
|
|
|
|
import android.net.http.SslCertificate; |
|
|
|
import android.net.http.SslError; |
|
|
|
import android.net.http.SslError; |
|
|
|
import android.os.Build; |
|
|
|
import android.os.Build; |
|
|
|
import android.os.Message; |
|
|
|
import android.os.Message; |
|
|
@ -31,14 +32,29 @@ import android.webkit.WebViewClient; |
|
|
|
import android.widget.EditText; |
|
|
|
import android.widget.EditText; |
|
|
|
import android.widget.TextView; |
|
|
|
import android.widget.TextView; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.BufferedInputStream; |
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
|
|
|
|
import java.io.FileNotFoundException; |
|
|
|
|
|
|
|
import java.io.InputStream; |
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.net.URISyntaxException; |
|
|
|
import java.net.URISyntaxException; |
|
|
|
|
|
|
|
import java.security.cert.Certificate; |
|
|
|
|
|
|
|
import java.security.cert.CertificateException; |
|
|
|
|
|
|
|
import java.security.cert.CertificateFactory; |
|
|
|
|
|
|
|
import java.security.cert.X509Certificate; |
|
|
|
|
|
|
|
import java.security.KeyStore; |
|
|
|
|
|
|
|
import java.security.KeyStoreException; |
|
|
|
|
|
|
|
import java.security.NoSuchAlgorithmException; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
import javax.inject.Inject; |
|
|
|
import javax.inject.Inject; |
|
|
|
|
|
|
|
import javax.net.ssl.TrustManager; |
|
|
|
|
|
|
|
import javax.net.ssl.TrustManagerFactory; |
|
|
|
|
|
|
|
import javax.net.ssl.X509TrustManager; |
|
|
|
|
|
|
|
|
|
|
|
import org.purplei2p.lightning.BuildConfig; |
|
|
|
import org.purplei2p.lightning.BuildConfig; |
|
|
|
import org.purplei2p.lightning.R; |
|
|
|
import org.purplei2p.lightning.R; |
|
|
@ -62,6 +78,8 @@ public class LightningWebClient extends WebViewClient { |
|
|
|
@NonNull private final UIController mUIController; |
|
|
|
@NonNull private final UIController mUIController; |
|
|
|
@NonNull private final IntentUtils mIntentUtils; |
|
|
|
@NonNull private final IntentUtils mIntentUtils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private TrustManagerFactory tmf = null; |
|
|
|
|
|
|
|
|
|
|
|
@Inject ProxyUtils mProxyUtils; |
|
|
|
@Inject ProxyUtils mProxyUtils; |
|
|
|
@Inject AdBlock mAdBlock; |
|
|
|
@Inject AdBlock mAdBlock; |
|
|
|
|
|
|
|
|
|
|
@ -74,6 +92,37 @@ public class LightningWebClient extends WebViewClient { |
|
|
|
mLightningView = lightningView; |
|
|
|
mLightningView = lightningView; |
|
|
|
mAdBlock.updatePreference(); |
|
|
|
mAdBlock.updatePreference(); |
|
|
|
mIntentUtils = new IntentUtils(activity); |
|
|
|
mIntentUtils = new IntentUtils(activity); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
initTrustStore(); |
|
|
|
|
|
|
|
} catch(Exception e) {} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void initTrustStore() throws |
|
|
|
|
|
|
|
CertificateException, FileNotFoundException, |
|
|
|
|
|
|
|
IOException, KeyStoreException, NoSuchAlgorithmException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create a KeyStore containing our trusted CAs
|
|
|
|
|
|
|
|
String keyStoreType = KeyStore.getDefaultType(); |
|
|
|
|
|
|
|
KeyStore trustedKeyStore = KeyStore.getInstance(keyStoreType); |
|
|
|
|
|
|
|
trustedKeyStore.load(null, null); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InputStream caInput = new BufferedInputStream(mActivity.getResources().getAssets().open("cert/purplei2p.crt")); |
|
|
|
|
|
|
|
Certificate ca; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
ca = cf.generateCertificate(caInput); |
|
|
|
|
|
|
|
Log.d(TAG, "ca-root DN=" + ((X509Certificate) ca).getSubjectDN()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
finally { |
|
|
|
|
|
|
|
caInput.close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
trustedKeyStore.setCertificateEntry("ca", ca); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create a TrustManager that trusts the CAs in our KeyStore
|
|
|
|
|
|
|
|
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); |
|
|
|
|
|
|
|
tmf = TrustManagerFactory.getInstance(tmfAlgorithm); |
|
|
|
|
|
|
|
tmf.init(trustedKeyStore); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP) |
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP) |
|
|
@ -225,6 +274,40 @@ public class LightningWebClient extends WebViewClient { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void onReceivedSslError(WebView view, @NonNull final SslErrorHandler handler, @NonNull SslError error) { |
|
|
|
public void onReceivedSslError(WebView view, @NonNull final SslErrorHandler handler, @NonNull SslError error) { |
|
|
|
|
|
|
|
boolean passVerify = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(error.getPrimaryError() == SslError.SSL_UNTRUSTED){ |
|
|
|
|
|
|
|
SslCertificate cert = error.getCertificate(); |
|
|
|
|
|
|
|
String subjectDN = cert.getIssuedTo().getDName(); |
|
|
|
|
|
|
|
Log.d(TAG, "SslError subjectDN: "+subjectDN); |
|
|
|
|
|
|
|
try{ |
|
|
|
|
|
|
|
Field f = cert.getClass().getDeclaredField("mX509Certificate"); |
|
|
|
|
|
|
|
f.setAccessible(true); |
|
|
|
|
|
|
|
X509Certificate x509 = (X509Certificate)f.get(cert); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
X509Certificate[] chain = {x509}; |
|
|
|
|
|
|
|
for (TrustManager trustManager: tmf.getTrustManagers()) { |
|
|
|
|
|
|
|
if (trustManager instanceof X509TrustManager) { |
|
|
|
|
|
|
|
X509TrustManager x509TrustManager = (X509TrustManager)trustManager; |
|
|
|
|
|
|
|
try{ |
|
|
|
|
|
|
|
x509TrustManager.checkServerTrusted(chain, "generic"); |
|
|
|
|
|
|
|
passVerify = true;break; |
|
|
|
|
|
|
|
}catch(Exception e){ |
|
|
|
|
|
|
|
Log.e(TAG, "SslError verify trustManager failed", e); |
|
|
|
|
|
|
|
passVerify = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Log.d(TAG, "SslError passVerify: "+passVerify); |
|
|
|
|
|
|
|
}catch(Exception e){ |
|
|
|
|
|
|
|
Log.e(TAG, "SslError verify cert fail", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(passVerify == true) { |
|
|
|
|
|
|
|
handler.proceed(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<Integer> errorCodeMessageCodes = getAllSslErrorMessageCodes(error); |
|
|
|
List<Integer> errorCodeMessageCodes = getAllSslErrorMessageCodes(error); |
|
|
|
|
|
|
|
|
|
|
|
StringBuilder stringBuilder = new StringBuilder(); |
|
|
|
StringBuilder stringBuilder = new StringBuilder(); |
|
|
|