mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-14 08:15:04 +01:00
Additions to SSL handling
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
6f5e6834f3
commit
4fa0dd6182
@ -21,9 +21,12 @@
|
|||||||
package com.nextcloud.talk.activities;
|
package com.nextcloud.talk.activities;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.SslErrorHandler;
|
||||||
|
|
||||||
import com.bluelinelabs.conductor.Conductor;
|
import com.bluelinelabs.conductor.Conductor;
|
||||||
import com.bluelinelabs.conductor.Router;
|
import com.bluelinelabs.conductor.Router;
|
||||||
@ -59,6 +62,8 @@ import io.requery.reactivex.ReactiveEntityStore;
|
|||||||
@AutoInjector(NextcloudTalkApplication.class)
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
public final class MainActivity extends AppCompatActivity implements ActionBarProvider {
|
public final class MainActivity extends AppCompatActivity implements ActionBarProvider {
|
||||||
|
|
||||||
|
private static final String TAG = "MainActivity";
|
||||||
|
|
||||||
@BindView(R.id.toolbar)
|
@BindView(R.id.toolbar)
|
||||||
Toolbar toolbar;
|
Toolbar toolbar;
|
||||||
@BindView(R.id.controller_container)
|
@BindView(R.id.controller_container)
|
||||||
@ -105,7 +110,8 @@ public final class MainActivity extends AppCompatActivity implements ActionBarPr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showCertificateDialog(X509Certificate cert, MagicTrustManager magicTrustManager) {
|
public void showCertificateDialog(X509Certificate cert, MagicTrustManager magicTrustManager,
|
||||||
|
@Nullable SslErrorHandler sslErrorHandler) {
|
||||||
DateFormat formatter = DateFormat.getDateInstance(DateFormat.LONG);
|
DateFormat formatter = DateFormat.getDateInstance(DateFormat.LONG);
|
||||||
String validFrom = formatter.format(cert.getNotBefore());
|
String validFrom = formatter.format(cert.getNotBefore());
|
||||||
String validUntil = formatter.format(cert.getNotAfter());
|
String validUntil = formatter.format(cert.getNotAfter());
|
||||||
@ -130,8 +136,8 @@ public final class MainActivity extends AppCompatActivity implements ActionBarPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
String dialogText = String.format(getResources()
|
String dialogText = String.format(getResources()
|
||||||
.getString(R.string.nc_certificate_dialog_text), issuedBy, issuedFor,
|
.getString(R.string.nc_certificate_dialog_text),
|
||||||
validFrom, validUntil);
|
issuedBy, issuedFor, validFrom, validUntil);
|
||||||
|
|
||||||
new LovelyStandardDialog(this)
|
new LovelyStandardDialog(this)
|
||||||
.setTopColorRes(R.color.darkRed)
|
.setTopColorRes(R.color.darkRed)
|
||||||
@ -142,22 +148,28 @@ public final class MainActivity extends AppCompatActivity implements ActionBarPr
|
|||||||
.setMessage(dialogText)
|
.setMessage(dialogText)
|
||||||
.setPositiveButton(R.string.nc_yes, v -> {
|
.setPositiveButton(R.string.nc_yes, v -> {
|
||||||
magicTrustManager.addCertInTrustStore(cert);
|
magicTrustManager.addCertInTrustStore(cert);
|
||||||
|
if (sslErrorHandler != null) {
|
||||||
|
sslErrorHandler.proceed();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.nc_no, view1 -> {
|
.setNegativeButton(R.string.nc_no, view1 -> {
|
||||||
router.setRoot(RouterTransaction.with(new
|
if (sslErrorHandler != null) {
|
||||||
ServerSelectionController()));
|
sslErrorHandler.cancel();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
} catch (CertificateParsingException e) {
|
} catch (CertificateParsingException e) {
|
||||||
e.printStackTrace();
|
Log.d(TAG, "Failed to parse the certificate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onMessageEvent(CertificateEvent event) {
|
public void onMessageEvent(CertificateEvent event) {
|
||||||
showCertificateDialog(event.getX509Certificate(), event.getMagicTrustManager());
|
showCertificateDialog(event.getX509Certificate(), event.getMagicTrustManager(), event.getSslErrorHandler());
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
|
@ -40,21 +40,21 @@ import com.nextcloud.talk.R;
|
|||||||
import com.nextcloud.talk.api.helpers.api.ApiHelper;
|
import com.nextcloud.talk.api.helpers.api.ApiHelper;
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
import com.nextcloud.talk.controllers.base.BaseController;
|
import com.nextcloud.talk.controllers.base.BaseController;
|
||||||
|
import com.nextcloud.talk.events.CertificateEvent;
|
||||||
import com.nextcloud.talk.models.LoginData;
|
import com.nextcloud.talk.models.LoginData;
|
||||||
import com.nextcloud.talk.persistence.entities.UserEntity;
|
import com.nextcloud.talk.persistence.entities.UserEntity;
|
||||||
import com.nextcloud.talk.utils.bundle.BundleBuilder;
|
import com.nextcloud.talk.utils.bundle.BundleBuilder;
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils;
|
import com.nextcloud.talk.utils.database.user.UserUtils;
|
||||||
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
||||||
import com.yarolegovich.lovelydialog.LovelyStandardDialog;
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -176,50 +176,7 @@ public class WebViewLoginController extends BaseController {
|
|||||||
magicTrustManager.checkServerTrusted(new X509Certificate[]{cert}, "generic");
|
magicTrustManager.checkServerTrusted(new X509Certificate[]{cert}, "generic");
|
||||||
handler.proceed();
|
handler.proceed();
|
||||||
} catch (CertificateException exception) {
|
} catch (CertificateException exception) {
|
||||||
DateFormat formatter = DateFormat.getDateInstance(DateFormat.LONG);
|
EventBus.getDefault().post(new CertificateEvent(cert, magicTrustManager, handler));
|
||||||
String validFrom = formatter.format(cert.getNotBefore());
|
|
||||||
String validUntil = formatter.format(cert.getNotAfter());
|
|
||||||
|
|
||||||
String issuedBy = cert.getIssuerDN().toString();
|
|
||||||
String issuedFor;
|
|
||||||
|
|
||||||
if (cert.getSubjectAlternativeNames() != null) {
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
for (Object o : cert.getSubjectAlternativeNames()) {
|
|
||||||
List list = (List) o;
|
|
||||||
int type = (Integer) list.get(0);
|
|
||||||
if (type == 2) {
|
|
||||||
String name = (String) list.get(1);
|
|
||||||
stringBuilder.append("[").append(type).append("]").append(name).append(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
issuedFor = stringBuilder.toString();
|
|
||||||
} else {
|
|
||||||
issuedFor = cert.getSubjectDN().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
String dialogText = String.format(getResources()
|
|
||||||
.getString(R.string.nc_certificate_dialog_text), issuedBy, issuedFor,
|
|
||||||
validFrom, validUntil);
|
|
||||||
|
|
||||||
new LovelyStandardDialog(getActivity())
|
|
||||||
.setTopColorRes(R.color.darkRed)
|
|
||||||
.setNegativeButtonColorRes(R.color.darkRed)
|
|
||||||
.setPositiveButtonColorRes(R.color.colorPrimaryDark)
|
|
||||||
.setIcon(R.drawable.ic_security_white_24dp)
|
|
||||||
.setTitle(R.string.nc_certificate_dialog_title)
|
|
||||||
.setMessage(dialogText)
|
|
||||||
.setPositiveButton(R.string.nc_yes, v -> {
|
|
||||||
magicTrustManager.addCertInTrustStore(cert);
|
|
||||||
handler.proceed();
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.nc_no, view1 -> {
|
|
||||||
handler.cancel();
|
|
||||||
getRouter().setRoot(RouterTransaction.with(new
|
|
||||||
ServerSelectionController()));
|
|
||||||
})
|
|
||||||
.setCancelable(false)
|
|
||||||
.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
|
@ -133,7 +133,7 @@ public class RestModule {
|
|||||||
|
|
||||||
httpClient.sslSocketFactory(sslSocketFactoryCompat, magicTrustManager);
|
httpClient.sslSocketFactory(sslSocketFactoryCompat, magicTrustManager);
|
||||||
httpClient.retryOnConnectionFailure(true);
|
httpClient.retryOnConnectionFailure(true);
|
||||||
httpClient.hostnameVerifier(new MagicTrustManager().getHostnameVerifier(OkHostnameVerifier.INSTANCE));
|
httpClient.hostnameVerifier(magicTrustManager.getHostnameVerifier(OkHostnameVerifier.INSTANCE));
|
||||||
|
|
||||||
if (!Proxy.NO_PROXY.equals(proxy)) {
|
if (!Proxy.NO_PROXY.equals(proxy)) {
|
||||||
httpClient.proxy(proxy);
|
httpClient.proxy(proxy);
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.events;
|
package com.nextcloud.talk.events;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.webkit.SslErrorHandler;
|
||||||
|
|
||||||
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
@ -27,10 +30,18 @@ import java.security.cert.X509Certificate;
|
|||||||
public class CertificateEvent {
|
public class CertificateEvent {
|
||||||
private final X509Certificate x509Certificate;
|
private final X509Certificate x509Certificate;
|
||||||
private final MagicTrustManager magicTrustManager;
|
private final MagicTrustManager magicTrustManager;
|
||||||
|
@Nullable private final SslErrorHandler sslErrorHandler;
|
||||||
|
|
||||||
public CertificateEvent(X509Certificate x509Certificate, MagicTrustManager magicTrustManager) {
|
public CertificateEvent(X509Certificate x509Certificate, MagicTrustManager magicTrustManager,
|
||||||
|
@Nullable SslErrorHandler sslErrorHandler) {
|
||||||
this.x509Certificate = x509Certificate;
|
this.x509Certificate = x509Certificate;
|
||||||
this.magicTrustManager = magicTrustManager;
|
this.magicTrustManager = magicTrustManager;
|
||||||
|
this.sslErrorHandler = sslErrorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public SslErrorHandler getSslErrorHandler() {
|
||||||
|
return sslErrorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public X509Certificate getX509Certificate() {
|
public X509Certificate getX509Certificate() {
|
||||||
|
@ -99,7 +99,8 @@ public class MagicTrustManager implements X509TrustManager {
|
|||||||
return true;
|
return true;
|
||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
if (!isCertInMagicTrustStore(x509Certificate)) {
|
if (!isCertInMagicTrustStore(x509Certificate)) {
|
||||||
EventBus.getDefault().post(new CertificateEvent(x509Certificate, this));
|
EventBus.getDefault().post(new CertificateEvent(x509Certificate, this,
|
||||||
|
null));
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
while (!isCertInMagicTrustStore(x509Certificate) && System.currentTimeMillis() <=
|
while (!isCertInMagicTrustStore(x509Certificate) && System.currentTimeMillis() <=
|
||||||
startTime + 15000) {
|
startTime + 15000) {
|
||||||
|
Loading…
Reference in New Issue
Block a user