|
|
@ -32,29 +32,14 @@ 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; |
|
|
@ -77,8 +62,6 @@ 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; |
|
|
|
|
|
|
|
|
|
|
|
LightningWebClient(@NonNull Activity activity, @NonNull LightningView lightningView) { |
|
|
|
LightningWebClient(@NonNull Activity activity, @NonNull LightningView lightningView) { |
|
|
@ -89,31 +72,6 @@ public class LightningWebClient extends WebViewClient { |
|
|
|
mUIController = (UIController) activity; |
|
|
|
mUIController = (UIController) activity; |
|
|
|
mLightningView = lightningView; |
|
|
|
mLightningView = lightningView; |
|
|
|
mIntentUtils = new IntentUtils(activity); |
|
|
|
mIntentUtils = new IntentUtils(activity); |
|
|
|
try { |
|
|
|
|
|
|
|
initTrustStore(); |
|
|
|
|
|
|
|
} catch(Exception e) {} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void initTrustStore() throws |
|
|
|
|
|
|
|
CertificateException, FileNotFoundException, |
|
|
|
|
|
|
|
IOException, KeyStoreException, NoSuchAlgorithmException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
|
|
|
|
|
|
|
InputStream caInput = mActivity.getResources().openRawResource(R.raw.purplei2p); |
|
|
|
|
|
|
|
final Certificate ca = cf.generateCertificate(caInput); |
|
|
|
|
|
|
|
Log.d(TAG, "ca-root DN=" + ((X509Certificate) ca).getSubjectDN()); |
|
|
|
|
|
|
|
caInput.close(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create a KeyStore containing our trusted CAs
|
|
|
|
|
|
|
|
String keyStoreType = KeyStore.getDefaultType(); |
|
|
|
|
|
|
|
KeyStore trustedKeyStore = KeyStore.getInstance(keyStoreType); |
|
|
|
|
|
|
|
trustedKeyStore.load(null, null); |
|
|
|
|
|
|
|
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) |
|
|
@ -257,42 +215,6 @@ 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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(error.getPrimaryError() == SslError.SSL_IDMISMATCH){ |
|
|
|
if(error.getPrimaryError() == SslError.SSL_IDMISMATCH){ |
|
|
|
// Due to strange bug in android when trust anchors used, we must revalidate that hostname in request and in certificate is not matching.
|
|
|
|
// Due to strange bug in android when trust anchors used, we must revalidate that hostname in request and in certificate is not matching.
|
|
|
|
SslCertificate cert = error.getCertificate(); |
|
|
|
SslCertificate cert = error.getCertificate(); |
|
|
|