Loading core/java/android/net/vcn/VcnControlPlaneConfig.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.PersistableBundle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * This class represents a control plane configuration for a Virtual Carrier Network connection. * * <p>Each {@link VcnGatewayConnectionConfig} must have a {@link VcnControlPlaneConfig}, containing * all connection, authentication and authorization parameters required to establish a Gateway * Connection with a remote endpoint. * * <p>A {@link VcnControlPlaneConfig} object can be shared by multiple {@link * VcnGatewayConnectionConfig}(s) if they will used for connecting with the same remote endpoint. * * @see VcnManager * @see VcnGatewayConnectionConfig * * @hide */ public abstract class VcnControlPlaneConfig { /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({CONFIG_TYPE_IKE}) public @interface ConfigType {} /** @hide */ public static final int CONFIG_TYPE_IKE = 1; private static final String CONFIG_TYPE_KEY = "mConfigType"; @ConfigType private final int mConfigType; /** * Package private constructor. * * @hide */ VcnControlPlaneConfig(int configType) { mConfigType = configType; } /** * Constructs a VcnControlPlaneConfig object by deserializing a PersistableBundle. * * @param in the {@link PersistableBundle} containing an {@link VcnControlPlaneConfig} object * @hide */ public static VcnControlPlaneConfig fromPersistableBundle(@NonNull PersistableBundle in) { Objects.requireNonNull(in, "PersistableBundle was null"); int configType = in.getInt(CONFIG_TYPE_KEY); switch (configType) { case CONFIG_TYPE_IKE: return new VcnControlPlaneIkeConfig(in); default: throw new IllegalStateException("Unrecognized configType: " + configType); } } /** * Converts this VcnControlPlaneConfig to a PersistableBundle. * * @hide */ @NonNull public PersistableBundle toPersistableBundle() { final PersistableBundle result = new PersistableBundle(); result.putInt(CONFIG_TYPE_KEY, mConfigType); return result; } /** @hide */ @Override public int hashCode() { return Objects.hash(mConfigType); } /** @hide */ @Override public boolean equals(Object o) { if (!(o instanceof VcnControlPlaneConfig)) { return false; } return mConfigType == ((VcnControlPlaneConfig) o).mConfigType; } } core/java/android/net/vcn/VcnControlPlaneIkeConfig.java 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; import android.os.PersistableBundle; import android.util.ArraySet; import java.util.Objects; /** * This class is an IKEv2 control plane configuration for a Virtual Carrier Network connection. * * <p>This class is an extension of the {@link VcnControlPlaneConfig}, containing IKEv2-specific * configuration, authentication and authorization parameters. * * @see VcnControlPlaneConfig * * @hide */ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName(); // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to // construct mIkeParams and mChildParams from PersistableBundles. private static final String IKE_PARAMS_KEY = "mIkeParams"; @Nullable private final IkeSessionParams mIkeParams; private static final String CHILD_PARAMS_KEY = "mChildParams"; @Nullable private final TunnelModeChildSessionParams mChildParams; private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>(); { BUNDLE_KEY_SET.add(IKE_PARAMS_KEY); BUNDLE_KEY_SET.add(CHILD_PARAMS_KEY); } /** * Constructs a VcnControlPlaneIkeConfig object. * * @param ikeParams the IKE Session negotiation parameters * @param childParams the tunnel mode Child Session negotiation parameters */ public VcnControlPlaneIkeConfig( @NonNull IkeSessionParams ikeParams, @NonNull TunnelModeChildSessionParams childParams) { super(CONFIG_TYPE_IKE); mIkeParams = ikeParams; mChildParams = childParams; validate(); } /** * Constructs a VcnControlPlaneIkeConfig object by deserializing a PersistableBundle. * * @param in the {@link PersistableBundle} containing an {@link VcnControlPlaneIkeConfig} object * @hide */ public VcnControlPlaneIkeConfig(@NonNull PersistableBundle in) { super(CONFIG_TYPE_IKE); final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY); final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY); // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from // PersistableBundles. mIkeParams = null; mChildParams = null; } private void validate() { Objects.requireNonNull(mIkeParams, "mIkeParams was null"); Objects.requireNonNull(mChildParams, "mChildParams was null"); } /** * Converts this VcnControlPlaneConfig to a PersistableBundle. * * @hide */ @Override @NonNull public PersistableBundle toPersistableBundle() { final PersistableBundle result = super.toPersistableBundle(); // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to // PersistableBundles. return result; } /** Retrieves the IKE Session configuration. */ @NonNull public IkeSessionParams getIkeSessionParams() { return mIkeParams; } /** Retrieves the tunnel mode Child Session configuration. */ @NonNull public TunnelModeChildSessionParams getChildSessionParams() { return mChildParams; } /** @hide */ @Override public int hashCode() { return Objects.hash(super.hashCode(), mIkeParams, mChildParams); } /** @hide */ @Override public boolean equals(Object o) { if (!(o instanceof VcnControlPlaneIkeConfig)) { return false; } VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o; return super.equals(o) && Objects.equals(mIkeParams, other.mIkeParams) && Objects.equals(mChildParams, other.mChildParams); } } tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeSaProposal; import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.SaProposal; import android.net.ipsec.ike.TunnelModeChildSessionParams; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class VcnControlPlaneIkeConfigTest { private static final IkeSessionParams IKE_PARAMS; private static final TunnelModeChildSessionParams CHILD_PARAMS; static { IkeSaProposal ikeProposal = new IkeSaProposal.Builder() .addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) .addDhGroup(DH_GROUP_2048_BIT_MODP) .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC) .build(); Context mockContext = mock(Context.class); ConnectivityManager mockConnectManager = mock(ConnectivityManager.class); doReturn(mockConnectManager) .when(mockContext) .getSystemService(Context.CONNECTIVITY_SERVICE); doReturn(mock(Network.class)).when(mockConnectManager).getActiveNetwork(); final String serverHostname = "192.0.2.100"; final String testLocalId = "test.client.com"; final String testRemoteId = "test.server.com"; final byte[] psk = "psk".getBytes(); IKE_PARAMS = new IkeSessionParams.Builder(mockContext) .setServerHostname(serverHostname) .addSaProposal(ikeProposal) .setLocalIdentification(new IkeFqdnIdentification(testLocalId)) .setRemoteIdentification(new IkeFqdnIdentification(testRemoteId)) .setAuthPsk(psk) .build(); ChildSaProposal childProposal = new ChildSaProposal.Builder() .addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) .build(); CHILD_PARAMS = new TunnelModeChildSessionParams.Builder().addSaProposal(childProposal).build(); } // Package private for use in VcnGatewayConnectionConfigTest static VcnControlPlaneIkeConfig buildTestConfig() { return new VcnControlPlaneIkeConfig(IKE_PARAMS, CHILD_PARAMS); } @Test public void testGetters() { final VcnControlPlaneIkeConfig config = buildTestConfig(); assertEquals(IKE_PARAMS, config.getIkeSessionParams()); assertEquals(CHILD_PARAMS, config.getChildSessionParams()); } @Test public void testConstructConfigWithoutIkeParams() { try { new VcnControlPlaneIkeConfig(null, CHILD_PARAMS); fail("Expect to fail because ikeParams was null"); } catch (NullPointerException expected) { } } @Test public void testBuilderConfigWithoutChildParams() { try { new VcnControlPlaneIkeConfig(IKE_PARAMS, null); fail("Expect to fail because childParams was null"); } catch (NullPointerException expected) { } } } Loading
core/java/android/net/vcn/VcnControlPlaneConfig.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.PersistableBundle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * This class represents a control plane configuration for a Virtual Carrier Network connection. * * <p>Each {@link VcnGatewayConnectionConfig} must have a {@link VcnControlPlaneConfig}, containing * all connection, authentication and authorization parameters required to establish a Gateway * Connection with a remote endpoint. * * <p>A {@link VcnControlPlaneConfig} object can be shared by multiple {@link * VcnGatewayConnectionConfig}(s) if they will used for connecting with the same remote endpoint. * * @see VcnManager * @see VcnGatewayConnectionConfig * * @hide */ public abstract class VcnControlPlaneConfig { /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({CONFIG_TYPE_IKE}) public @interface ConfigType {} /** @hide */ public static final int CONFIG_TYPE_IKE = 1; private static final String CONFIG_TYPE_KEY = "mConfigType"; @ConfigType private final int mConfigType; /** * Package private constructor. * * @hide */ VcnControlPlaneConfig(int configType) { mConfigType = configType; } /** * Constructs a VcnControlPlaneConfig object by deserializing a PersistableBundle. * * @param in the {@link PersistableBundle} containing an {@link VcnControlPlaneConfig} object * @hide */ public static VcnControlPlaneConfig fromPersistableBundle(@NonNull PersistableBundle in) { Objects.requireNonNull(in, "PersistableBundle was null"); int configType = in.getInt(CONFIG_TYPE_KEY); switch (configType) { case CONFIG_TYPE_IKE: return new VcnControlPlaneIkeConfig(in); default: throw new IllegalStateException("Unrecognized configType: " + configType); } } /** * Converts this VcnControlPlaneConfig to a PersistableBundle. * * @hide */ @NonNull public PersistableBundle toPersistableBundle() { final PersistableBundle result = new PersistableBundle(); result.putInt(CONFIG_TYPE_KEY, mConfigType); return result; } /** @hide */ @Override public int hashCode() { return Objects.hash(mConfigType); } /** @hide */ @Override public boolean equals(Object o) { if (!(o instanceof VcnControlPlaneConfig)) { return false; } return mConfigType == ((VcnControlPlaneConfig) o).mConfigType; } }
core/java/android/net/vcn/VcnControlPlaneIkeConfig.java 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; import android.os.PersistableBundle; import android.util.ArraySet; import java.util.Objects; /** * This class is an IKEv2 control plane configuration for a Virtual Carrier Network connection. * * <p>This class is an extension of the {@link VcnControlPlaneConfig}, containing IKEv2-specific * configuration, authentication and authorization parameters. * * @see VcnControlPlaneConfig * * @hide */ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName(); // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to // construct mIkeParams and mChildParams from PersistableBundles. private static final String IKE_PARAMS_KEY = "mIkeParams"; @Nullable private final IkeSessionParams mIkeParams; private static final String CHILD_PARAMS_KEY = "mChildParams"; @Nullable private final TunnelModeChildSessionParams mChildParams; private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>(); { BUNDLE_KEY_SET.add(IKE_PARAMS_KEY); BUNDLE_KEY_SET.add(CHILD_PARAMS_KEY); } /** * Constructs a VcnControlPlaneIkeConfig object. * * @param ikeParams the IKE Session negotiation parameters * @param childParams the tunnel mode Child Session negotiation parameters */ public VcnControlPlaneIkeConfig( @NonNull IkeSessionParams ikeParams, @NonNull TunnelModeChildSessionParams childParams) { super(CONFIG_TYPE_IKE); mIkeParams = ikeParams; mChildParams = childParams; validate(); } /** * Constructs a VcnControlPlaneIkeConfig object by deserializing a PersistableBundle. * * @param in the {@link PersistableBundle} containing an {@link VcnControlPlaneIkeConfig} object * @hide */ public VcnControlPlaneIkeConfig(@NonNull PersistableBundle in) { super(CONFIG_TYPE_IKE); final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY); final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY); // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from // PersistableBundles. mIkeParams = null; mChildParams = null; } private void validate() { Objects.requireNonNull(mIkeParams, "mIkeParams was null"); Objects.requireNonNull(mChildParams, "mChildParams was null"); } /** * Converts this VcnControlPlaneConfig to a PersistableBundle. * * @hide */ @Override @NonNull public PersistableBundle toPersistableBundle() { final PersistableBundle result = super.toPersistableBundle(); // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to // PersistableBundles. return result; } /** Retrieves the IKE Session configuration. */ @NonNull public IkeSessionParams getIkeSessionParams() { return mIkeParams; } /** Retrieves the tunnel mode Child Session configuration. */ @NonNull public TunnelModeChildSessionParams getChildSessionParams() { return mChildParams; } /** @hide */ @Override public int hashCode() { return Objects.hash(super.hashCode(), mIkeParams, mChildParams); } /** @hide */ @Override public boolean equals(Object o) { if (!(o instanceof VcnControlPlaneIkeConfig)) { return false; } VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o; return super.equals(o) && Objects.equals(mIkeParams, other.mIkeParams) && Objects.equals(mChildParams, other.mChildParams); } }
tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.vcn; import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeSaProposal; import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.SaProposal; import android.net.ipsec.ike.TunnelModeChildSessionParams; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class VcnControlPlaneIkeConfigTest { private static final IkeSessionParams IKE_PARAMS; private static final TunnelModeChildSessionParams CHILD_PARAMS; static { IkeSaProposal ikeProposal = new IkeSaProposal.Builder() .addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) .addDhGroup(DH_GROUP_2048_BIT_MODP) .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC) .build(); Context mockContext = mock(Context.class); ConnectivityManager mockConnectManager = mock(ConnectivityManager.class); doReturn(mockConnectManager) .when(mockContext) .getSystemService(Context.CONNECTIVITY_SERVICE); doReturn(mock(Network.class)).when(mockConnectManager).getActiveNetwork(); final String serverHostname = "192.0.2.100"; final String testLocalId = "test.client.com"; final String testRemoteId = "test.server.com"; final byte[] psk = "psk".getBytes(); IKE_PARAMS = new IkeSessionParams.Builder(mockContext) .setServerHostname(serverHostname) .addSaProposal(ikeProposal) .setLocalIdentification(new IkeFqdnIdentification(testLocalId)) .setRemoteIdentification(new IkeFqdnIdentification(testRemoteId)) .setAuthPsk(psk) .build(); ChildSaProposal childProposal = new ChildSaProposal.Builder() .addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) .build(); CHILD_PARAMS = new TunnelModeChildSessionParams.Builder().addSaProposal(childProposal).build(); } // Package private for use in VcnGatewayConnectionConfigTest static VcnControlPlaneIkeConfig buildTestConfig() { return new VcnControlPlaneIkeConfig(IKE_PARAMS, CHILD_PARAMS); } @Test public void testGetters() { final VcnControlPlaneIkeConfig config = buildTestConfig(); assertEquals(IKE_PARAMS, config.getIkeSessionParams()); assertEquals(CHILD_PARAMS, config.getChildSessionParams()); } @Test public void testConstructConfigWithoutIkeParams() { try { new VcnControlPlaneIkeConfig(null, CHILD_PARAMS); fail("Expect to fail because ikeParams was null"); } catch (NullPointerException expected) { } } @Test public void testBuilderConfigWithoutChildParams() { try { new VcnControlPlaneIkeConfig(IKE_PARAMS, null); fail("Expect to fail because childParams was null"); } catch (NullPointerException expected) { } } }