From 94d31add64e7f281b5082985f65193577a57b987 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 17 Jan 2020 19:41:38 -0800 Subject: [PATCH] Add support for starting IKEv2/IPsec VPNs from settings This commit allows the startLegacyVpn() call to start Platform VPN profiles, allowing Settings to use the IKEv2/IPsec VPN options When using an aliased private key, the Ikev2VpnProfile.KEYSTORE_ALIAS_PREFIX must be prepended to the front of the alias. This will in turn result in the fromVpnProfile() function to pull the key from the KeyStore, as opposed to the inline-key that the VpnManager API uses. Bug: 148991741 Test: FrameworksNetTests passing, new tests added in subsequent CL Test: Manually tested Change-Id: Icbca695c353b2e12e99305676404dbf1a4495949 --- .../java/android/net/Ikev2VpnProfileTest.java | 5 +- .../android/server/connectivity/VpnTest.java | 51 ++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java index d6a2176d7e..2273bc6122 100644 --- a/tests/net/java/android/net/Ikev2VpnProfileTest.java +++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; import android.test.mock.MockContext; @@ -232,10 +231,12 @@ public class Ikev2VpnProfileTest { builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa); final VpnProfile profile = builder.build().toVpnProfile(); + final String expectedSecret = Ikev2VpnProfile.PREFIX_INLINE + + Ikev2VpnProfile.encodeForIpsecSecret(mPrivateKey.getEncoded()); verifyVpnProfileCommon(profile); assertEquals(Ikev2VpnProfile.certificateToPemString(mUserCert), profile.ipsecUserCert); assertEquals( - Ikev2VpnProfile.encodeForIpsecSecret(mPrivateKey.getEncoded()), + expectedSecret, profile.ipsecSecret); assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert); diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 0e3b797613..1994d1f2ed 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -59,9 +59,15 @@ import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.res.Resources; import android.net.ConnectivityManager; +import android.net.Ikev2VpnProfile; +import android.net.InetAddresses; +import android.net.IpPrefix; +import android.net.IpSecManager; +import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo.DetailedState; +import android.net.RouteInfo; import android.net.UidRange; import android.net.VpnManager; import android.net.VpnService; @@ -84,6 +90,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; +import com.android.server.IpSecService; import org.junit.Before; import org.junit.Test; @@ -93,6 +100,7 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.net.Inet4Address; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -125,6 +133,9 @@ public class VpnTest { } static final String TEST_VPN_PKG = "com.dummy.vpn"; + private static final String TEST_VPN_SERVER = "1.2.3.4"; + private static final String TEST_VPN_IDENTITY = "identity"; + private static final byte[] TEST_VPN_PSK = "psk".getBytes(); /** * Names and UIDs for some fake packages. Important points: @@ -151,23 +162,39 @@ public class VpnTest { @Mock private Vpn.SystemServices mSystemServices; @Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator; @Mock private ConnectivityManager mConnectivityManager; + @Mock private IpSecService mIpSecService; @Mock private KeyStore mKeyStore; - private final VpnProfile mVpnProfile = new VpnProfile("key"); + private final VpnProfile mVpnProfile; + + private IpSecManager mIpSecManager; + + public VpnTest() throws Exception { + // Build an actual VPN profile that is capable of being converted to and from an + // Ikev2VpnProfile + final Ikev2VpnProfile.Builder builder = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY); + builder.setAuthPsk(TEST_VPN_PSK); + mVpnProfile = builder.build().toVpnProfile(); + } @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mIpSecManager = new IpSecManager(mContext, mIpSecService); + when(mContext.getPackageManager()).thenReturn(mPackageManager); setMockedPackages(mPackages); - when(mContext.getPackageName()).thenReturn(Vpn.class.getPackage().getName()); + when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG); + when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG); when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps); when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE))) .thenReturn(mNotificationManager); when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE))) .thenReturn(mConnectivityManager); + when(mContext.getSystemService(eq(Context.IPSEC_SERVICE))).thenReturn(mIpSecManager); when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) .thenReturn(Resources.getSystem().getString( R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)); @@ -962,6 +989,26 @@ public class VpnTest { // a subsequent CL. } + @Test + public void testStartLegacyVpn() throws Exception { + final Vpn vpn = createVpn(primaryUser.id); + setMockedUsers(primaryUser); + + // Dummy egress interface + final String egressIface = "DUMMY0"; + final LinkProperties lp = new LinkProperties(); + lp.setInterfaceName(egressIface); + + final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), + InetAddresses.parseNumericAddress("192.0.2.0"), egressIface); + lp.addRoute(defaultRoute); + + vpn.startLegacyVpn(mVpnProfile, mKeyStore, lp); + + // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in + // a subsequent CL. + } + /** * Mock some methods of vpn object. */