Merge "Create VcnControlPlaneConfig and VcnControlPlaneIkeConfig"
This commit is contained in:
107
core/java/android/net/vcn/VcnControlPlaneConfig.java
Normal file
107
core/java/android/net/vcn/VcnControlPlaneConfig.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
142
core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
Normal file
142
core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
118
tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
Normal file
118
tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user