Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 332f7389 authored by Yan Yan's avatar Yan Yan
Browse files

Add three new IKE options in IkeSessionParamsUtils

This commit updates IkeSessionParamsUtils to be able
to encode/decode IkeSessionParams with IKE_OPTION_REKEY_MOBILITY,
IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION and
IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES.

This commit can also maintain compatibility with older T IPsec
modules that do not support the two IKE_OPTION_AUTOMATIC_ options

Bug: 242231517
Test: atest IkeSessionParamsUtilsTest
Change-Id: Icadbe98b3df3cf3a80f51dc1467eb99753d82216
parent c271a2da
Loading
Loading
Loading
Loading
+37 −3
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
import android.os.PersistableBundle;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.vcn.util.PersistableBundleUtils;
@@ -58,6 +59,8 @@ import java.util.Set;
 */
@VisibleForTesting(visibility = Visibility.PRIVATE)
public final class IkeSessionParamsUtils {
    private static final String TAG = IkeSessionParamsUtils.class.getSimpleName();

    private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY";
    private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY";
    private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY";
@@ -72,6 +75,13 @@ public final class IkeSessionParamsUtils {
    private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY";
    private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY";

    // TODO: b/243181760 Use the IKE API when they are exposed
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static final int IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION = 6;

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static final int IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES = 7;

    private static final Set<Integer> IKE_OPTIONS = new ArraySet<>();

    static {
@@ -80,6 +90,26 @@ public final class IkeSessionParamsUtils {
        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_FORCE_PORT_4500);
        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT);
        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY);
        IKE_OPTIONS.add(IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION);
        IKE_OPTIONS.add(IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES);
    }

    /**
     * Check if an IKE option is supported in the IPsec module installed on the device
     *
     * <p>This method ensures caller to safely access options that are added between dessert
     * releases.
     */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static boolean isIkeOptionValid(int option) {
        try {
            new IkeSessionParams.Builder().addIkeOption(option);
            return true;
        } catch (IllegalArgumentException e) {
            Log.d(TAG, "Option not supported; discarding: " + option);
            return false;
        }
    }

    /** Serializes an IkeSessionParams to a PersistableBundle. */
@@ -130,7 +160,7 @@ public final class IkeSessionParamsUtils {
        // IKE_OPTION is defined in IKE module and added in the IkeSessionParams
        final List<Integer> enabledIkeOptions = new ArrayList<>();
        for (int option : IKE_OPTIONS) {
            if (params.hasIkeOption(option)) {
            if (isIkeOptionValid(option) && params.hasIkeOption(option)) {
                enabledIkeOptions.add(option);
            }
        }
@@ -205,13 +235,17 @@ public final class IkeSessionParamsUtils {

        // Clear IKE Options that are by default enabled
        for (int option : IKE_OPTIONS) {
            if (isIkeOptionValid(option)) {
                builder.removeIkeOption(option);
            }
        }

        final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY);
        for (int option : optionArray) {
            if (isIkeOptionValid(option)) {
                builder.addIkeOption(option);
            }
        }

        return builder.build();
    }
+30 −17
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.net.vcn.persistablebundleutils;

import static android.net.vcn.persistablebundleutils.IkeSessionParamsUtils.IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION;
import static android.net.vcn.persistablebundleutils.IkeSessionParamsUtils.IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES;
import static android.net.vcn.persistablebundleutils.IkeSessionParamsUtils.isIkeOptionValid;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.telephony.TelephonyManager.APPTYPE_USIM;
@@ -134,15 +137,37 @@ public class IkeSessionParamsUtilsTest {
        verifyPersistableBundleEncodeDecodeIsLossless(params);
    }

    private static IkeSessionParams.Builder createBuilderMinimumWithEap() throws Exception {
        final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");

        final byte[] eapId = "test@android.net".getBytes(StandardCharsets.US_ASCII);
        final int subId = 1;
        final EapSessionConfig eapConfig =
                new EapSessionConfig.Builder()
                        .setEapIdentity(eapId)
                        .setEapSimConfig(subId, APPTYPE_USIM)
                        .setEapAkaConfig(subId, APPTYPE_USIM)
                        .build();
        return createBuilderMinimum().setAuthEap(serverCaCert, eapConfig);
    }

    @Test
    public void testEncodeDecodeParamsWithIkeOptions() throws Exception {
        final IkeSessionParams params =
                createBuilderMinimum()
        final IkeSessionParams.Builder builder =
                createBuilderMinimumWithEap()
                        .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
                        .addIkeOption(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH)
                        .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
                        .addIkeOption(IkeSessionParams.IKE_OPTION_FORCE_PORT_4500)
                        .addIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT)
                        .build();
        verifyPersistableBundleEncodeDecodeIsLossless(params);
                        .addIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY);
        if (isIkeOptionValid(IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION)) {
            builder.addIkeOption(IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION);
        }
        if (isIkeOptionValid(IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES)) {
            builder.addIkeOption(IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES);
        }
        verifyPersistableBundleEncodeDecodeIsLossless(builder.build());
    }

    private static InputStream openAssetsFile(String fileName) throws Exception {
@@ -176,19 +201,7 @@ public class IkeSessionParamsUtilsTest {

    @Test
    public void testEncodeRecodeParamsWithEapAuth() throws Exception {
        final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");

        final byte[] eapId = "test@android.net".getBytes(StandardCharsets.US_ASCII);
        final int subId = 1;
        final EapSessionConfig eapConfig =
                new EapSessionConfig.Builder()
                        .setEapIdentity(eapId)
                        .setEapSimConfig(subId, APPTYPE_USIM)
                        .setEapAkaConfig(subId, APPTYPE_USIM)
                        .build();

        final IkeSessionParams params =
                createBuilderMinimum().setAuthEap(serverCaCert, eapConfig).build();
        final IkeSessionParams params = createBuilderMinimumWithEap().build();
        verifyPersistableBundleEncodeDecodeIsLossless(params);
    }
}