From b9e1f2354520e37f0e2784f156f1288e55e1a993 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 18 Jul 2022 18:29:15 +0200 Subject: update soon expiring vpn certificates after connecting to the VPN --- .../leap/bitmaskclient/base/models/Provider.java | 10 ++++++++ .../main/java/se/leap/bitmaskclient/eip/EIP.java | 19 +++++++++++++++ .../leap/bitmaskclient/eip/EipSetupObserver.java | 8 +++++++ .../bitmaskclient/eip/VpnCertificateValidator.java | 27 ++++++++++++++++------ .../bitmaskclient/providersetup/ProviderAPI.java | 6 +++++ .../providersetup/ProviderApiManagerBase.java | 21 +++++++++++++++++ 6 files changed, 84 insertions(+), 7 deletions(-) (limited to 'app/src/main/java/se/leap') diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java index 974aef80..02a9694a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java @@ -63,6 +63,7 @@ public final class Provider implements Parcelable { private String vpnCertificate = ""; private long lastEipServiceUpdate = 0L; private long lastGeoIpUpdate = 0L; + private boolean shouldUpdateVpnCertificate; private boolean allowAnonymous; private boolean allowRegistered; @@ -361,6 +362,7 @@ public final class Provider implements Parcelable { parcel.writeString(getVpnCertificate()); parcel.writeLong(lastEipServiceUpdate); parcel.writeLong(lastGeoIpUpdate); + parcel.writeInt(shouldUpdateVpnCertificate ? 0 : 1); } @@ -407,6 +409,7 @@ public final class Provider implements Parcelable { } this.lastEipServiceUpdate = in.readLong(); this.lastGeoIpUpdate = in.readLong(); + this.shouldUpdateVpnCertificate = in.readInt() == 0; } catch (MalformedURLException | JSONException e) { e.printStackTrace(); } @@ -492,6 +495,13 @@ public final class Provider implements Parcelable { return System.currentTimeMillis() - lastEipServiceUpdate >= EIP_SERVICE_TIMEOUT; } + public void setShouldUpdateVpnCertificate(Boolean update) { + shouldUpdateVpnCertificate = update; + } + + public boolean shouldUpdateVpnCertificate() { + return shouldUpdateVpnCertificate; + } public void setLastGeoIpUpdate(long timestamp) { lastGeoIpUpdate = timestamp; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index cf4dc9bf..46f91781 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -56,6 +56,7 @@ import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.OnBootReceiver; +import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.base.utils.PreferenceHelper; @@ -242,6 +243,12 @@ public final class EIP extends JobIntentService implements Observer { return; } + if (shouldUpdateVPNCertificate()) { + Provider p = ProviderObservable.getInstance().getCurrentProvider(); + p.setShouldUpdateVpnCertificate(true); + ProviderObservable.getInstance().updateProvider(p); + } + GatewaysManager gatewaysManager = new GatewaysManager(getApplicationContext()); if (gatewaysManager.isEmpty()) { setErrorResult(result, warning_client_parsing_error_gateways, null); @@ -267,6 +274,12 @@ public final class EIP extends JobIntentService implements Observer { Gateway gateway = gatewaysManager.select(0); Bundle result = new Bundle(); + if (shouldUpdateVPNCertificate()) { + Provider p = ProviderObservable.getInstance().getCurrentProvider(); + p.setShouldUpdateVpnCertificate(true); + ProviderObservable.getInstance().updateProvider(p); + } + launchActiveGateway(gateway, 0, result); if (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)){ VpnStatus.logWarning("ALWAYS-ON VPN: " + getString(R.string.no_vpn_profiles_defined)); @@ -415,6 +428,12 @@ public final class EIP extends JobIntentService implements Observer { return validator.isValid(); } + private boolean shouldUpdateVPNCertificate() { + VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); + return validator.shouldBeUpdated(); + } + + /** * helper function to add error to result bundle * diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index 9d67340e..56350703 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -39,12 +39,14 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.DELAY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.QUIETLY_UPDATE_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_EXCEPTION; import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_TIMEOUT; import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE; @@ -373,6 +375,12 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta if (shouldCheckAppUpdate()) { DownloadServiceCommand.execute(appContext, CHECK_VERSION_FILE); } + + if (provider.shouldUpdateVpnCertificate()) { + Bundle parameters = new Bundle(); + parameters.putLong(DELAY, 500); + ProviderAPICommand.execute(appContext, QUIETLY_UPDATE_VPN_CERTIFICATE, parameters, provider); + } finishGatewaySetup(false); } else if ("TCP_CONNECT".equals(state)) { changingGateway.set(false); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java index 16d1c5ad..8841ae94 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java @@ -45,9 +45,22 @@ public class VpnCertificateValidator { /** * - * @return true if all certificates are valid for more than 15 more days + * @return true if all certificates are valid for 1 more day */ public boolean isValid() { + return isValid(1); + } + + /** + * + * @return return true if certificates will expire in 8 days or less + */ + public boolean shouldBeUpdated() { + return !isValid(8); + } + + + private boolean isValid(int offsetDays) { if (certificate.isEmpty()) { return false; } @@ -57,7 +70,7 @@ public class VpnCertificateValidator { return false; } for (X509Certificate cert : x509Certificates) { - if (!isValid(cert)) { + if (!isValid(cert, offsetDays)) { return false; } } @@ -65,12 +78,12 @@ public class VpnCertificateValidator { } - private boolean isValid(X509Certificate certificate) { + private boolean isValid(X509Certificate certificate, int offsetDays) { if (certificate == null) { return false; } - Calendar offsetDate = calculateOffsetCertificateValidity(certificate); + Calendar offsetDate = calculateOffsetCertificateValidity(certificate, offsetDays); try { certificate.checkValidity(offsetDate.getTime()); return true; @@ -81,15 +94,15 @@ public class VpnCertificateValidator { } } - private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { + private Calendar calculateOffsetCertificateValidity(X509Certificate certificate, int offsetDays) { Calendar limitDate = calendarProvider.getCalendar(); Date startDate = certificate.getNotBefore(); // if certificates start date is before current date just return the current date without an offset if (startDate.getTime() >= limitDate.getTime().getTime()) { return limitDate; } - // else add an offset of 15 days to the current date - limitDate.add(Calendar.DAY_OF_YEAR, 15); + // else add an offset to the current date + limitDate.add(Calendar.DAY_OF_YEAR, offsetDays); return limitDate; } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index da77af2f..063c9e00 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -63,9 +63,15 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB SIGN_UP = "srpRegister", LOG_IN = "srpAuth", LOG_OUT = "logOut", + // all vpn certificate download commands are used in different scenarios with different error handling + // command key used for the initial vpn certificate download during the provider setup DOWNLOAD_VPN_CERTIFICATE = "downloadUserAuthedVPNCertificate", + // command key used to update soon expiring but yet valid certificates after connecting to the vpn + QUIETLY_UPDATE_VPN_CERTIFICATE = "ProviderAPI.QUIETLY_UPDATE_VPN_CERTIFICATE", + // command key used to update invalid certificates, connecting to the vpn is impossible UPDATE_INVALID_VPN_CERTIFICATE = "ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE", PARAMETERS = "parameters", + DELAY = "delay", RECEIVER_KEY = "receiver", ERRORS = "errors", ERRORID = "errorId", diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index ecddb9c7..607339fd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -52,6 +52,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOAD import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.DELAY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DOWNLOAD_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DOWNLOAD_SERVICE_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE; @@ -71,6 +72,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.MISSING_NETWORK_CO import static se.leap.bitmaskclient.providersetup.ProviderAPI.PARAMETERS; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.QUIETLY_UPDATE_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.RECEIVER_KEY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SIGN_UP; @@ -193,6 +195,14 @@ public abstract class ProviderApiManagerBase { return; } + if (parameters.containsKey(DELAY)) { + try { + Thread.sleep(parameters.getLong(DELAY)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (!serviceCallback.hasNetworkConnection()) { Bundle result = new Bundle(); setErrorResult(result, R.string.error_network_connection, null); @@ -277,6 +287,17 @@ public abstract class ProviderApiManagerBase { } ProviderObservable.getInstance().setProviderForDns(null); break; + case QUIETLY_UPDATE_VPN_CERTIFICATE: + ProviderObservable.getInstance().setProviderForDns(provider); + result = updateVpnCertificate(provider); + if (result.getBoolean(BROADCAST_RESULT_KEY)) { + Log.d(TAG, "successfully downloaded VPN certificate"); + provider.setShouldUpdateVpnCertificate(false); + PreferenceHelper.storeProviderInPreferences(preferences, provider); + ProviderObservable.getInstance().updateProvider(provider); + } + ProviderObservable.getInstance().setProviderForDns(null); + break; case UPDATE_INVALID_VPN_CERTIFICATE: ProviderObservable.getInstance().setProviderForDns(provider); result = updateVpnCertificate(provider); -- cgit v1.2.3