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

Commit 85414c1c authored by Yan Yan's avatar Yan Yan
Browse files

Support converting IkeConfigRequest to/from PersistableBundle

Bug: 163604823
Test: FrameworksVcnTests(add new tests)
Change-Id: I9a0f7ad91de41749fdf05629bf86bdb010ba13fb
parent c3da07fb
Loading
Loading
Loading
Loading
+96 −2
Original line number Diff line number Diff line
@@ -16,22 +16,31 @@

package android.net.vcn.persistablebundleutils;

import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;

import static com.android.internal.annotations.VisibleForTesting.Visibility;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.InetAddresses;
import android.net.eap.EapSessionConfig;
import android.net.ipsec.ike.IkeSaProposal;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
import android.os.PersistableBundle;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.vcn.util.PersistableBundleUtils;

import java.net.InetAddress;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
@@ -53,6 +62,7 @@ public final class IkeSessionParamsUtils {
    private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY";
    private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY";
    private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY";
    private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY";
    private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY";
    private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY";
    private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY";
@@ -89,13 +99,21 @@ public final class IkeSessionParamsUtils {
        result.putPersistableBundle(
                REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig()));

        final List<ConfigRequest> reqList = new ArrayList<>();
        for (IkeConfigRequest req : params.getConfigurationRequests()) {
            reqList.add(new ConfigRequest(req));
        }
        final PersistableBundle configReqListBundle =
                PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle);
        result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle);

        result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis());
        result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds());
        result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds());
        result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds());
        result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds());

        // TODO: Handle configuration requests and IKE options.
        // TODO: Handle IKE options.

        return result;
    }
@@ -136,7 +154,33 @@ public final class IkeSessionParamsUtils {
        builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY));
        builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY));

        // TODO: Handle configuration requests and IKE options.
        final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY);
        Objects.requireNonNull(configReqListBundle, "Config request list was null");
        final List<ConfigRequest> reqList =
                PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new);
        for (ConfigRequest req : reqList) {
            switch (req.type) {
                case ConfigRequest.IPV4_P_CSCF_ADDRESS:
                    if (req.address == null) {
                        builder.addPcscfServerRequest(AF_INET);
                    } else {
                        builder.addPcscfServerRequest(req.address);
                    }
                    break;
                case ConfigRequest.IPV6_P_CSCF_ADDRESS:
                    if (req.address == null) {
                        builder.addPcscfServerRequest(AF_INET6);
                    } else {
                        builder.addPcscfServerRequest(req.address);
                    }
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Unrecognized config request type: " + req.type);
            }
        }

        // TODO: Handle IKE options.

        return builder.build();
    }
@@ -389,4 +433,54 @@ public final class IkeSessionParamsUtils {
            builder.setAuthEap(serverCaCert, eapConfig);
        }
    }

    private static final class ConfigRequest {
        private static final int IPV4_P_CSCF_ADDRESS = 1;
        private static final int IPV6_P_CSCF_ADDRESS = 2;

        private static final String TYPE_KEY = "type";
        private static final String ADDRESS_KEY = "address";

        public final int type;

        // Null when it is an empty request
        @Nullable public final InetAddress address;

        ConfigRequest(IkeConfigRequest config) {
            if (config instanceof ConfigRequestIpv4PcscfServer) {
                type = IPV4_P_CSCF_ADDRESS;
                address = ((ConfigRequestIpv4PcscfServer) config).getAddress();
            } else if (config instanceof ConfigRequestIpv6PcscfServer) {
                type = IPV6_P_CSCF_ADDRESS;
                address = ((ConfigRequestIpv6PcscfServer) config).getAddress();
            } else {
                throw new IllegalStateException("Unknown TunnelModeChildConfigRequest");
            }
        }

        ConfigRequest(PersistableBundle in) {
            Objects.requireNonNull(in, "PersistableBundle was null");

            type = in.getInt(TYPE_KEY);

            String addressStr = in.getString(ADDRESS_KEY);
            if (addressStr == null) {
                address = null;
            } else {
                address = InetAddresses.parseNumericAddress(addressStr);
            }
        }

        @NonNull
        public PersistableBundle toPersistableBundle() {
            final PersistableBundle result = new PersistableBundle();

            result.putInt(TYPE_KEY, type);
            if (address != null) {
                result.putString(ADDRESS_KEY, address.getHostAddress());
            }

            return result;
        }
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.net.vcn.persistablebundleutils;

import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.telephony.TelephonyManager.APPTYPE_USIM;

import static org.junit.Assert.assertEquals;
@@ -38,6 +40,8 @@ import org.junit.runner.RunWith;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateFactory;
@@ -103,6 +107,23 @@ public class IkeSessionParamsUtilsTest {
        verifyPersistableBundleEncodeDecodeIsLossless(params);
    }

    @Test
    public void testEncodeRecodeParamsWithConfigRequests() throws Exception {
        final Inet4Address ipv4Address =
                (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.100");
        final Inet6Address ipv6Address =
                (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1");

        final IkeSessionParams params =
                createBuilderMinimum()
                        .addPcscfServerRequest(AF_INET)
                        .addPcscfServerRequest(AF_INET6)
                        .addPcscfServerRequest(ipv4Address)
                        .addPcscfServerRequest(ipv6Address)
                        .build();
        verifyPersistableBundleEncodeDecodeIsLossless(params);
    }

    @Test
    public void testEncodeRecodeParamsWithAuthPsk() throws Exception {
        final IkeSessionParams params = createBuilderMinimum().setAuthPsk("psk".getBytes()).build();