From: Markus Pfeiffer Date: Tue, 21 Nov 2023 14:37:24 +0000 (+0100) Subject: android: Add manager for managed trusted certificates X-Git-Tag: android-2.5.0^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa06d7549178cfdabcae865cbefd6a9fc491060d;p=thirdparty%2Fstrongswan.git android: Add manager for managed trusted certificates 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. --- 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 index 0000000000..395949a3dc --- /dev/null +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/ManagedTrustedCertificateManager.java @@ -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 . + * + * 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 configured = certificateRepository.getConfiguredCertificates(); + final List installed = certificateRepository.getInstalledCertificates(); + + final Difference 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 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 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); + } +}