]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Add manager for managed trusted certificates
authorMarkus Pfeiffer <markus.pfeiffer@relution.io>
Tue, 21 Nov 2023 14:37:24 +0000 (15:37 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 21 Feb 2024 11:24:53 +0000 (12:24 +0100)
This is used to install, replace or delete currently installed trusted
certificates based on the app's current managed configuration.

Certificates that are shared between multiple profiles are protected
and not uninstalled if a profile that uses it remains.

src/frontends/android/app/src/main/java/org/strongswan/android/logic/ManagedTrustedCertificateManager.java [new file with mode: 0644]

diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/ManagedTrustedCertificateManager.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/ManagedTrustedCertificateManager.java
new file mode 100644 (file)
index 0000000..395949a
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 Relution GmbH
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+package org.strongswan.android.logic;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+
+import org.strongswan.android.data.DatabaseHelper;
+import org.strongswan.android.data.ManagedConfigurationService;
+import org.strongswan.android.data.ManagedTrustedCertificate;
+import org.strongswan.android.data.ManagedTrustedCertificateRepository;
+import org.strongswan.android.utils.Difference;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+import androidx.annotation.NonNull;
+import androidx.core.util.Pair;
+
+public class ManagedTrustedCertificateManager
+{
+       private static final String TAG = ManagedTrustedCertificateManager.class.getSimpleName();
+
+       @NonNull
+       private final ExecutorService executorService;
+       @NonNull
+       private final Handler handler;
+
+       @NonNull
+       private final ManagedTrustedCertificateRepository certificateRepository;
+       @NonNull
+       private final ManagedTrustedCertificateInstaller certificateInstaller;
+
+       public ManagedTrustedCertificateManager(
+               @NonNull final Context context,
+               @NonNull final ExecutorService executorService,
+               @NonNull final Handler handler,
+               @NonNull final ManagedConfigurationService managedConfigurationService,
+               @NonNull final DatabaseHelper databaseHelper)
+       {
+               this.executorService = executorService;
+               this.handler = handler;
+
+               this.certificateRepository = new ManagedTrustedCertificateRepository(managedConfigurationService, databaseHelper);
+               this.certificateInstaller = new ManagedTrustedCertificateInstaller(context);
+       }
+
+       public void update(@NonNull final Runnable onUpdateCompleted)
+       {
+               executorService.execute(() -> {
+                       final List<ManagedTrustedCertificate> configured = certificateRepository.getConfiguredCertificates();
+                       final List<ManagedTrustedCertificate> installed = certificateRepository.getInstalledCertificates();
+
+                       final Difference<ManagedTrustedCertificate> diff = Difference.between(installed, configured, ManagedTrustedCertificate::getVpnProfileUuid);
+                       if (diff.isEmpty())
+                       {
+                               Log.d(TAG, "No trusted certificates changed, nothing to do");
+                               handler.post(onUpdateCompleted);
+                               return;
+                       }
+                       Log.d(TAG, "Trusted certificates changed " + diff);
+
+                       final Set<String> protectedAliases = new HashSet<>();
+                       for (final ManagedTrustedCertificate unchanged : diff.getUnchanged())
+                       {
+                               protectedAliases.add(unchanged.getAlias());
+                       }
+
+                       for (final ManagedTrustedCertificate delete : diff.getDeletes())
+                       {
+                               remove(delete, !protectedAliases.contains(delete.getAlias()));
+                       }
+
+                       for (final Pair<ManagedTrustedCertificate, ManagedTrustedCertificate> update : diff.getUpdates())
+                       {
+                               remove(update.first, !protectedAliases.contains(update.first.getAlias()));
+                               install(update.second);
+                       }
+
+                       for (final ManagedTrustedCertificate insert : diff.getInserts())
+                       {
+                               install(insert);
+                       }
+
+                       TrustedCertificateManager.getInstance().reset();
+                       TrustedCertificateManager.getInstance().load();
+                       handler.post(onUpdateCompleted);
+               });
+       }
+
+       private void install(@NonNull final ManagedTrustedCertificate trustedCertificate)
+       {
+               if (certificateInstaller.tryInstall(trustedCertificate))
+               {
+                       certificateRepository.addInstalledCertificate(trustedCertificate);
+               }
+       }
+
+       private void remove(@NonNull final ManagedTrustedCertificate trustedCertificate, boolean uninstall)
+       {
+               if (uninstall)
+               {
+                       certificateInstaller.tryRemove(trustedCertificate);
+               }
+               certificateRepository.removeInstalledCertificate(trustedCertificate);
+       }
+}