blob: 529d03c520bab395d62756525722599b93bd7575 [file] [log] [blame]
Nathan Harold2e9a5202017-09-26 11:44:23 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
evitayane4259d32018-03-22 17:53:08 -070019import static android.system.OsConstants.AF_INET;
20import static android.system.OsConstants.AF_INET6;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080021
Nathan Harold2e9a5202017-09-26 11:44:23 -070022import static org.junit.Assert.assertEquals;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080023import static org.junit.Assert.assertNotNull;
Benedict Wong0febe5e2017-08-22 21:42:33 -070024import static org.junit.Assert.fail;
Nathan Harold2e9a5202017-09-26 11:44:23 -070025import static org.mockito.Matchers.anyInt;
Nathan Harold2e9a5202017-09-26 11:44:23 -070026import static org.mockito.Matchers.anyString;
27import static org.mockito.Matchers.eq;
28import static org.mockito.Mockito.mock;
Nathan Harold22795302018-02-27 19:19:40 -080029import static org.mockito.Mockito.times;
Nathan Harold2e9a5202017-09-26 11:44:23 -070030import static org.mockito.Mockito.verify;
31import static org.mockito.Mockito.when;
32
Nathan Harold21208ee2018-03-15 18:06:06 -070033import android.app.AppOpsManager;
Nathan Harold2e9a5202017-09-26 11:44:23 -070034import android.content.Context;
Benedict Wonge265d5f2018-11-08 19:45:34 -080035import android.content.pm.PackageManager;
Nathan Harold2e9a5202017-09-26 11:44:23 -070036import android.net.INetd;
37import android.net.IpSecAlgorithm;
38import android.net.IpSecConfig;
39import android.net.IpSecManager;
40import android.net.IpSecSpiResponse;
evitayan0a7d3e32018-03-22 13:42:07 -070041import android.net.IpSecTransform;
Nathan Harold2e9a5202017-09-26 11:44:23 -070042import android.net.IpSecTransformResponse;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080043import android.net.IpSecTunnelInterfaceResponse;
evitayan0a7d3e32018-03-22 13:42:07 -070044import android.net.IpSecUdpEncapResponse;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080045import android.net.LinkAddress;
46import android.net.Network;
Nathan Harold2e9a5202017-09-26 11:44:23 -070047import android.net.NetworkUtils;
48import android.os.Binder;
Benedict Wongd78ad3d2020-03-25 05:50:51 +000049import android.os.INetworkManagementService;
Nathan Harold2e9a5202017-09-26 11:44:23 -070050import android.os.ParcelFileDescriptor;
Benedict Wong344bd622017-11-16 15:27:22 -080051import android.system.Os;
Benedict Wonga0989622018-07-25 13:06:29 -070052import android.test.mock.MockContext;
Nathan Harold2e9a5202017-09-26 11:44:23 -070053
Brett Chabot1ae2aa62019-03-04 14:14:56 -080054import androidx.test.filters.SmallTest;
Nathan Harold2e9a5202017-09-26 11:44:23 -070055
56import org.junit.Before;
Nathan Harold8c69bcb2018-05-15 19:18:38 -070057import org.junit.Ignore;
Nathan Harold2e9a5202017-09-26 11:44:23 -070058import org.junit.Test;
59import org.junit.runner.RunWith;
60import org.junit.runners.Parameterized;
61
Benedict Wonge265d5f2018-11-08 19:45:34 -080062import java.net.Inet4Address;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080063import java.net.Socket;
64import java.util.Arrays;
65import java.util.Collection;
66
Nathan Harold2e9a5202017-09-26 11:44:23 -070067/** Unit tests for {@link IpSecService}. */
68@SmallTest
69@RunWith(Parameterized.class)
70public class IpSecServiceParameterizedTest {
71
Nathan Harolda2523312018-01-05 19:25:13 -080072 private static final int TEST_SPI = 0xD1201D;
Nathan Harold2e9a5202017-09-26 11:44:23 -070073
Nathan Harold5676f5f2018-01-16 19:34:01 -080074 private final String mSourceAddr;
evitayane4259d32018-03-22 17:53:08 -070075 private final String mDestinationAddr;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080076 private final LinkAddress mLocalInnerAddress;
evitayane4259d32018-03-22 17:53:08 -070077 private final int mFamily;
Nathan Harold2e9a5202017-09-26 11:44:23 -070078
Benedict Wong781dae62018-09-06 11:31:25 -070079 private static final int[] ADDRESS_FAMILIES =
80 new int[] {AF_INET, AF_INET6};
81
Nathan Harold2e9a5202017-09-26 11:44:23 -070082 @Parameterized.Parameters
83 public static Collection ipSecConfigs() {
Benedict Wongecc9f7c2018-03-01 18:53:07 -080084 return Arrays.asList(
85 new Object[][] {
evitayane4259d32018-03-22 17:53:08 -070086 {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET},
87 {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6}
Benedict Wongecc9f7c2018-03-01 18:53:07 -080088 });
Nathan Harold2e9a5202017-09-26 11:44:23 -070089 }
90
Benedict Wong4ebc2c52017-11-01 17:14:25 -070091 private static final byte[] AEAD_KEY = {
92 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
93 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
94 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
95 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
96 0x73, 0x61, 0x6C, 0x74
97 };
Nathan Harold2e9a5202017-09-26 11:44:23 -070098 private static final byte[] CRYPT_KEY = {
99 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
100 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
101 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
102 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
103 };
104 private static final byte[] AUTH_KEY = {
105 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
107 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
109 };
110
Nathan Harold21208ee2018-03-15 18:06:06 -0700111 AppOpsManager mMockAppOps = mock(AppOpsManager.class);
112
113 MockContext mMockContext = new MockContext() {
114 @Override
115 public Object getSystemService(String name) {
116 switch(name) {
117 case Context.APP_OPS_SERVICE:
118 return mMockAppOps;
119 default:
120 return null;
121 }
122 }
123
124 @Override
Benedict Wonge265d5f2018-11-08 19:45:34 -0800125 public PackageManager getPackageManager() {
126 return mMockPkgMgr;
127 }
128
129 @Override
Nathan Harold21208ee2018-03-15 18:06:06 -0700130 public void enforceCallingOrSelfPermission(String permission, String message) {
131 if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
132 return;
133 }
134 throw new SecurityException("Unavailable permission requested");
135 }
136 };
137
Nathan Harold2e9a5202017-09-26 11:44:23 -0700138 INetd mMockNetd;
Benedict Wongd78ad3d2020-03-25 05:50:51 +0000139 INetworkManagementService mNetworkManager;
Benedict Wonge265d5f2018-11-08 19:45:34 -0800140 PackageManager mMockPkgMgr;
Nathan Harold2e9a5202017-09-26 11:44:23 -0700141 IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
142 IpSecService mIpSecService;
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800143 Network fakeNetwork = new Network(0xAB);
Benedict Wonga0989622018-07-25 13:06:29 -0700144 int mUid = Os.getuid();
Nathan Harold2e9a5202017-09-26 11:44:23 -0700145
Benedict Wong0febe5e2017-08-22 21:42:33 -0700146 private static final IpSecAlgorithm AUTH_ALGO =
147 new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
148 private static final IpSecAlgorithm CRYPT_ALGO =
149 new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
150 private static final IpSecAlgorithm AEAD_ALGO =
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700151 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
evitayan0a7d3e32018-03-22 13:42:07 -0700152 private static final int REMOTE_ENCAP_PORT = 4500;
Benedict Wong0febe5e2017-08-22 21:42:33 -0700153
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800154 public IpSecServiceParameterizedTest(
evitayane4259d32018-03-22 17:53:08 -0700155 String sourceAddr, String destAddr, String localInnerAddr, int family) {
Nathan Harold5676f5f2018-01-16 19:34:01 -0800156 mSourceAddr = sourceAddr;
157 mDestinationAddr = destAddr;
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800158 mLocalInnerAddress = new LinkAddress(localInnerAddr);
evitayane4259d32018-03-22 17:53:08 -0700159 mFamily = family;
Nathan Harold2e9a5202017-09-26 11:44:23 -0700160 }
161
162 @Before
163 public void setUp() throws Exception {
Nathan Harold2e9a5202017-09-26 11:44:23 -0700164 mMockNetd = mock(INetd.class);
Benedict Wongd78ad3d2020-03-25 05:50:51 +0000165 mNetworkManager = mock(INetworkManagementService.class);
Benedict Wonge265d5f2018-11-08 19:45:34 -0800166 mMockPkgMgr = mock(PackageManager.class);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700167 mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
Benedict Wongd78ad3d2020-03-25 05:50:51 +0000168 mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700169
170 // Injecting mock netd
171 when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
Benedict Wonge265d5f2018-11-08 19:45:34 -0800172
173 // PackageManager should always return true (feature flag tests in IpSecServiceTest)
174 when(mMockPkgMgr.hasSystemFeature(anyString())).thenReturn(true);
175
Nathan Harold21208ee2018-03-15 18:06:06 -0700176 // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
177 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage")))
178 .thenReturn(AppOpsManager.MODE_ALLOWED);
179 // A system package will not be granted the app op, so this should fall back to
180 // a permissions check, which should pass.
181 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("systemPackage")))
182 .thenReturn(AppOpsManager.MODE_DEFAULT);
183 // A mismatch between the package name and the UID will return MODE_IGNORED.
184 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("badPackage")))
185 .thenReturn(AppOpsManager.MODE_IGNORED);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700186 }
187
evitayan0a7d3e32018-03-22 13:42:07 -0700188 //TODO: Add a test to verify SPI.
189
Nathan Harold2e9a5202017-09-26 11:44:23 -0700190 @Test
191 public void testIpSecServiceReserveSpi() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800192 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
193 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700194
195 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800196 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800197 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700198 assertEquals(IpSecManager.Status.OK, spiResp.status);
Nathan Harolda2523312018-01-05 19:25:13 -0800199 assertEquals(TEST_SPI, spiResp.spi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700200 }
201
202 @Test
203 public void testReleaseSecurityParameterIndex() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800204 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
205 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700206
207 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800208 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800209 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700210
211 mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
212
213 verify(mMockNetd)
214 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700215 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800216 anyString(),
217 anyString(),
218 eq(TEST_SPI),
219 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700220 anyInt(),
Di Lu0b611f42018-01-11 11:35:25 -0800221 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800222
223 // Verify quota and RefcountedResource objects cleaned up
Benedict Wonga0989622018-07-25 13:06:29 -0700224 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800225 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
226 try {
227 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
228 fail("Expected IllegalArgumentException on attempt to access deleted resource");
229 } catch (IllegalArgumentException expected) {
230
231 }
232 }
233
234 @Test
235 public void testSecurityParameterIndexBinderDeath() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800236 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
237 .thenReturn(TEST_SPI);
Benedict Wong344bd622017-11-16 15:27:22 -0800238
239 IpSecSpiResponse spiResp =
Nathan Harold660a3352017-12-14 14:46:46 -0800240 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800241 mDestinationAddr, TEST_SPI, new Binder());
Benedict Wong344bd622017-11-16 15:27:22 -0800242
Benedict Wonga0989622018-07-25 13:06:29 -0700243 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800244 IpSecService.RefcountedResource refcountedRecord =
245 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
246
247 refcountedRecord.binderDied();
248
249 verify(mMockNetd)
250 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700251 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800252 anyString(),
253 anyString(),
254 eq(TEST_SPI),
255 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700256 anyInt(),
Di Lu0b611f42018-01-11 11:35:25 -0800257 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800258
259 // Verify quota and RefcountedResource objects cleaned up
260 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
261 try {
262 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
263 fail("Expected IllegalArgumentException on attempt to access deleted resource");
264 } catch (IllegalArgumentException expected) {
265
266 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700267 }
268
Nathan Harolda2523312018-01-05 19:25:13 -0800269 private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception {
270 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt()))
Benedict Wong0febe5e2017-08-22 21:42:33 -0700271 .thenReturn(returnSpi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700272
Benedict Wong0febe5e2017-08-22 21:42:33 -0700273 IpSecSpiResponse spi =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800274 mIpSecService.allocateSecurityParameterIndex(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700275 NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
276 IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
277 new Binder());
278 return spi.resourceId;
279 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700280
Benedict Wong0febe5e2017-08-22 21:42:33 -0700281 private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800282 config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI));
Nathan Harold5676f5f2018-01-16 19:34:01 -0800283 config.setSourceAddress(mSourceAddr);
Nathan Harolda2523312018-01-05 19:25:13 -0800284 config.setDestinationAddress(mDestinationAddr);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700285 }
286
287 private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800288 config.setEncryption(CRYPT_ALGO);
289 config.setAuthentication(AUTH_ALGO);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700290 }
291
evitayan0a7d3e32018-03-22 13:42:07 -0700292 private void addEncapSocketToIpSecConfig(int resourceId, IpSecConfig config) throws Exception {
293 config.setEncapType(IpSecTransform.ENCAP_ESPINUDP);
294 config.setEncapSocketResourceId(resourceId);
295 config.setEncapRemotePort(REMOTE_ENCAP_PORT);
296 }
297
298 private void verifyTransformNetdCalledForCreatingSA(
299 IpSecConfig config, IpSecTransformResponse resp) throws Exception {
300 verifyTransformNetdCalledForCreatingSA(config, resp, 0);
301 }
302
303 private void verifyTransformNetdCalledForCreatingSA(
304 IpSecConfig config, IpSecTransformResponse resp, int encapSocketPort) throws Exception {
305 IpSecAlgorithm auth = config.getAuthentication();
306 IpSecAlgorithm crypt = config.getEncryption();
307 IpSecAlgorithm authCrypt = config.getAuthenticatedEncryption();
308
309 verify(mMockNetd, times(1))
310 .ipSecAddSecurityAssociation(
311 eq(mUid),
312 eq(config.getMode()),
313 eq(config.getSourceAddress()),
314 eq(config.getDestinationAddress()),
315 eq((config.getNetwork() != null) ? config.getNetwork().netId : 0),
316 eq(TEST_SPI),
317 eq(0),
318 eq(0),
319 eq((auth != null) ? auth.getName() : ""),
320 eq((auth != null) ? auth.getKey() : new byte[] {}),
321 eq((auth != null) ? auth.getTruncationLengthBits() : 0),
322 eq((crypt != null) ? crypt.getName() : ""),
323 eq((crypt != null) ? crypt.getKey() : new byte[] {}),
324 eq((crypt != null) ? crypt.getTruncationLengthBits() : 0),
325 eq((authCrypt != null) ? authCrypt.getName() : ""),
326 eq((authCrypt != null) ? authCrypt.getKey() : new byte[] {}),
327 eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0),
328 eq(config.getEncapType()),
329 eq(encapSocketPort),
Benedict Wong781dae62018-09-06 11:31:25 -0700330 eq(config.getEncapRemotePort()),
331 eq(config.getXfrmInterfaceId()));
evitayan0a7d3e32018-03-22 13:42:07 -0700332 }
333
Nathan Harold2e9a5202017-09-26 11:44:23 -0700334 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800335 public void testCreateTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700336 IpSecConfig ipSecConfig = new IpSecConfig();
337 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
338 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700339
340 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700341 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Nathan Harold2e9a5202017-09-26 11:44:23 -0700342 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
343
evitayan0a7d3e32018-03-22 13:42:07 -0700344 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700345 }
346
347 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800348 public void testCreateTransformAead() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700349 IpSecConfig ipSecConfig = new IpSecConfig();
350 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
351
Nathan Harolda2523312018-01-05 19:25:13 -0800352 ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700353
354 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700355 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wong0febe5e2017-08-22 21:42:33 -0700356 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
357
evitayan0a7d3e32018-03-22 13:42:07 -0700358 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
359 }
360
361 @Test
362 public void testCreateTransportModeTransformWithEncap() throws Exception {
363 IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
364
365 IpSecConfig ipSecConfig = new IpSecConfig();
366 ipSecConfig.setMode(IpSecTransform.MODE_TRANSPORT);
367 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
368 addAuthAndCryptToIpSecConfig(ipSecConfig);
369 addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
370
evitayane4259d32018-03-22 17:53:08 -0700371 if (mFamily == AF_INET) {
372 IpSecTransformResponse createTransformResp =
373 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
374 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
evitayan0a7d3e32018-03-22 13:42:07 -0700375
evitayane4259d32018-03-22 17:53:08 -0700376 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
377 } else {
378 try {
379 IpSecTransformResponse createTransformResp =
380 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
381 fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
382 } catch (IllegalArgumentException expected) {
383 }
384 }
evitayan0a7d3e32018-03-22 13:42:07 -0700385 }
386
387 @Test
388 public void testCreateTunnelModeTransformWithEncap() throws Exception {
389 IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
390
391 IpSecConfig ipSecConfig = new IpSecConfig();
392 ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
393 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
394 addAuthAndCryptToIpSecConfig(ipSecConfig);
395 addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
396
evitayane4259d32018-03-22 17:53:08 -0700397 if (mFamily == AF_INET) {
398 IpSecTransformResponse createTransformResp =
399 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
400 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
evitayan0a7d3e32018-03-22 13:42:07 -0700401
evitayane4259d32018-03-22 17:53:08 -0700402 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
403 } else {
404 try {
405 IpSecTransformResponse createTransformResp =
406 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
407 fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
408 } catch (IllegalArgumentException expected) {
409 }
410 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700411 }
412
Andreas Gampea7b26b52018-02-26 08:06:30 -0800413 @Test
Benedict Wonge6b42772017-12-13 18:26:40 -0800414 public void testCreateTwoTransformsWithSameSpis() throws Exception {
415 IpSecConfig ipSecConfig = new IpSecConfig();
416 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
417 addAuthAndCryptToIpSecConfig(ipSecConfig);
418
419 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700420 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800421 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
422
423 // Attempting to create transform a second time with the same SPIs should throw an error...
424 try {
Nathan Harold21208ee2018-03-15 18:06:06 -0700425 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800426 fail("IpSecService should have thrown an error for reuse of SPI");
427 } catch (IllegalStateException expected) {
428 }
429
430 // ... even if the transform is deleted
431 mIpSecService.deleteTransform(createTransformResp.resourceId);
432 try {
Nathan Harold21208ee2018-03-15 18:06:06 -0700433 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800434 fail("IpSecService should have thrown an error for reuse of SPI");
435 } catch (IllegalStateException expected) {
436 }
437 }
438
Nathan Harold2e9a5202017-09-26 11:44:23 -0700439 @Test
Nathan Harold22795302018-02-27 19:19:40 -0800440 public void testReleaseOwnedSpi() throws Exception {
441 IpSecConfig ipSecConfig = new IpSecConfig();
442 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
443 addAuthAndCryptToIpSecConfig(ipSecConfig);
444
445 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700446 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonga0989622018-07-25 13:06:29 -0700447 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Nathan Harold22795302018-02-27 19:19:40 -0800448 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
449 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
450 verify(mMockNetd, times(0))
451 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700452 eq(mUid),
Nathan Harold22795302018-02-27 19:19:40 -0800453 anyString(),
454 anyString(),
455 eq(TEST_SPI),
456 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700457 anyInt(),
Nathan Harold22795302018-02-27 19:19:40 -0800458 anyInt());
459 // quota is not released until the SPI is released by the Transform
460 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
461 }
462
463 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800464 public void testDeleteTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700465 IpSecConfig ipSecConfig = new IpSecConfig();
466 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
467 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700468
469 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700470 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wongf33f03132018-01-18 14:38:16 -0800471 mIpSecService.deleteTransform(createTransformResp.resourceId);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700472
Nathan Harold22795302018-02-27 19:19:40 -0800473 verify(mMockNetd, times(1))
Nathan Harold2e9a5202017-09-26 11:44:23 -0700474 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700475 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800476 anyString(),
477 anyString(),
478 eq(TEST_SPI),
479 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700480 anyInt(),
Di Lu0b611f42018-01-11 11:35:25 -0800481 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800482
483 // Verify quota and RefcountedResource objects cleaned up
Benedict Wonga0989622018-07-25 13:06:29 -0700484 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800485 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
Nathan Harold22795302018-02-27 19:19:40 -0800486 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
487
488 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
489 // Verify that ipSecDeleteSa was not called when the SPI was released because the
490 // ownedByTransform property should prevent it; (note, the called count is cumulative).
491 verify(mMockNetd, times(1))
492 .ipSecDeleteSecurityAssociation(
493 anyInt(),
494 anyString(),
495 anyString(),
496 anyInt(),
497 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700498 anyInt(),
Nathan Harold22795302018-02-27 19:19:40 -0800499 anyInt());
500 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
501
Benedict Wong344bd622017-11-16 15:27:22 -0800502 try {
503 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
504 createTransformResp.resourceId);
505 fail("Expected IllegalArgumentException on attempt to access deleted resource");
506 } catch (IllegalArgumentException expected) {
507
508 }
509 }
510
511 @Test
512 public void testTransportModeTransformBinderDeath() throws Exception {
513 IpSecConfig ipSecConfig = new IpSecConfig();
514 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
515 addAuthAndCryptToIpSecConfig(ipSecConfig);
516
517 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700518 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wong344bd622017-11-16 15:27:22 -0800519
Benedict Wonga0989622018-07-25 13:06:29 -0700520 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800521 IpSecService.RefcountedResource refcountedRecord =
522 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
523 createTransformResp.resourceId);
524
525 refcountedRecord.binderDied();
526
527 verify(mMockNetd)
528 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700529 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800530 anyString(),
531 anyString(),
532 eq(TEST_SPI),
533 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700534 anyInt(),
Di Lu0b611f42018-01-11 11:35:25 -0800535 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800536
537 // Verify quota and RefcountedResource objects cleaned up
538 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
539 try {
540 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
541 createTransformResp.resourceId);
542 fail("Expected IllegalArgumentException on attempt to access deleted resource");
543 } catch (IllegalArgumentException expected) {
544
545 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700546 }
547
548 @Test
549 public void testApplyTransportModeTransform() throws Exception {
Benedict Wonge6963902020-03-10 23:38:04 -0700550 verifyApplyTransportModeTransformCommon(false);
551 }
552
553 @Test
554 public void testApplyTransportModeTransformReleasedSpi() throws Exception {
555 verifyApplyTransportModeTransformCommon(true);
556 }
557
558 public void verifyApplyTransportModeTransformCommon(
559 boolean closeSpiBeforeApply) throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700560 IpSecConfig ipSecConfig = new IpSecConfig();
561 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
562 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700563
564 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700565 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Josh Gao42bd8e12018-10-31 12:26:40 -0700566
Benedict Wonge6963902020-03-10 23:38:04 -0700567 if (closeSpiBeforeApply) {
568 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
569 }
570
Josh Gao42bd8e12018-10-31 12:26:40 -0700571 Socket socket = new Socket();
572 socket.bind(null);
573 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700574
575 int resourceId = createTransformResp.resourceId;
Nathan Harolda2523312018-01-05 19:25:13 -0800576 mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700577
578 verify(mMockNetd)
579 .ipSecApplyTransportModeTransform(
Luke Huange8e522b2018-11-23 12:01:41 +0800580 eq(pfd),
Benedict Wonga0989622018-07-25 13:06:29 -0700581 eq(mUid),
Nathan Harolda2523312018-01-05 19:25:13 -0800582 eq(IpSecManager.DIRECTION_OUT),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700583 anyString(),
584 anyString(),
Nathan Harolda2523312018-01-05 19:25:13 -0800585 eq(TEST_SPI));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700586 }
587
588 @Test
Benedict Wong963502f2019-10-03 11:09:00 -0700589 public void testApplyTransportModeTransformWithClosedSpi() throws Exception {
590 IpSecConfig ipSecConfig = new IpSecConfig();
591 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
592 addAuthAndCryptToIpSecConfig(ipSecConfig);
593
594 IpSecTransformResponse createTransformResp =
595 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
596
597 // Close SPI record
598 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
599
600 Socket socket = new Socket();
601 socket.bind(null);
602 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
603
604 int resourceId = createTransformResp.resourceId;
605 mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
606
607 verify(mMockNetd)
608 .ipSecApplyTransportModeTransform(
609 eq(pfd),
610 eq(mUid),
611 eq(IpSecManager.DIRECTION_OUT),
612 anyString(),
613 anyString(),
614 eq(TEST_SPI));
615 }
616
617 @Test
Nathan Harold2e9a5202017-09-26 11:44:23 -0700618 public void testRemoveTransportModeTransform() throws Exception {
Josh Gao42bd8e12018-10-31 12:26:40 -0700619 Socket socket = new Socket();
620 socket.bind(null);
621 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
Nathan Haroldf73d2522018-01-17 01:00:20 -0800622 mIpSecService.removeTransportModeTransforms(pfd);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700623
Luke Huange8e522b2018-11-23 12:01:41 +0800624 verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700625 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800626
627 private IpSecTunnelInterfaceResponse createAndValidateTunnel(
Nathan Harold21208ee2018-03-15 18:06:06 -0700628 String localAddr, String remoteAddr, String pkgName) {
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800629 IpSecTunnelInterfaceResponse createTunnelResp =
630 mIpSecService.createTunnelInterface(
Nathan Harold21208ee2018-03-15 18:06:06 -0700631 mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800632
633 assertNotNull(createTunnelResp);
634 assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
635 return createTunnelResp;
636 }
637
638 @Test
639 public void testCreateTunnelInterface() throws Exception {
640 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700641 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800642
643 // Check that we have stored the tracking object, and retrieve it
Benedict Wonga0989622018-07-25 13:06:29 -0700644 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800645 IpSecService.RefcountedResource refcountedRecord =
646 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
647 createTunnelResp.resourceId);
648
649 assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
650 verify(mMockNetd)
Benedict Wong781dae62018-09-06 11:31:25 -0700651 .ipSecAddTunnelInterface(
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800652 eq(createTunnelResp.interfaceName),
653 eq(mSourceAddr),
654 eq(mDestinationAddr),
655 anyInt(),
Benedict Wong781dae62018-09-06 11:31:25 -0700656 anyInt(),
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800657 anyInt());
Benedict Wongd78ad3d2020-03-25 05:50:51 +0000658 verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800659 }
660
661 @Test
662 public void testDeleteTunnelInterface() throws Exception {
663 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700664 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800665
Benedict Wonga0989622018-07-25 13:06:29 -0700666 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800667
Nathan Harold21208ee2018-03-15 18:06:06 -0700668 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800669
670 // Verify quota and RefcountedResource objects cleaned up
671 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
Benedict Wong781dae62018-09-06 11:31:25 -0700672 verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800673 try {
674 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
675 createTunnelResp.resourceId);
676 fail("Expected IllegalArgumentException on attempt to access deleted resource");
677 } catch (IllegalArgumentException expected) {
678 }
679 }
680
681 @Test
682 public void testTunnelInterfaceBinderDeath() throws Exception {
683 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700684 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800685
Benedict Wonga0989622018-07-25 13:06:29 -0700686 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800687 IpSecService.RefcountedResource refcountedRecord =
688 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
689 createTunnelResp.resourceId);
690
691 refcountedRecord.binderDied();
692
693 // Verify quota and RefcountedResource objects cleaned up
694 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
Benedict Wong781dae62018-09-06 11:31:25 -0700695 verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800696 try {
697 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
698 createTunnelResp.resourceId);
699 fail("Expected IllegalArgumentException on attempt to access deleted resource");
700 } catch (IllegalArgumentException expected) {
701 }
702 }
703
704 @Test
Benedict Wong781dae62018-09-06 11:31:25 -0700705 public void testApplyTunnelModeTransform() throws Exception {
Benedict Wonge6963902020-03-10 23:38:04 -0700706 verifyApplyTunnelModeTransformCommon(false);
707 }
708
709 @Test
710 public void testApplyTunnelModeTransformReleasedSpi() throws Exception {
711 verifyApplyTunnelModeTransformCommon(true);
712 }
713
714 public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply) throws Exception {
Benedict Wong781dae62018-09-06 11:31:25 -0700715 IpSecConfig ipSecConfig = new IpSecConfig();
716 ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
717 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
718 addAuthAndCryptToIpSecConfig(ipSecConfig);
719
720 IpSecTransformResponse createTransformResp =
721 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
722 IpSecTunnelInterfaceResponse createTunnelResp =
723 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
724
Benedict Wonge6963902020-03-10 23:38:04 -0700725 if (closeSpiBeforeApply) {
726 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
727 }
728
Benedict Wong781dae62018-09-06 11:31:25 -0700729 int transformResourceId = createTransformResp.resourceId;
730 int tunnelResourceId = createTunnelResp.resourceId;
731 mIpSecService.applyTunnelModeTransform(tunnelResourceId, IpSecManager.DIRECTION_OUT,
732 transformResourceId, "blessedPackage");
733
734 for (int selAddrFamily : ADDRESS_FAMILIES) {
735 verify(mMockNetd)
736 .ipSecUpdateSecurityPolicy(
737 eq(mUid),
738 eq(selAddrFamily),
739 eq(IpSecManager.DIRECTION_OUT),
740 anyString(),
741 anyString(),
742 eq(TEST_SPI),
743 anyInt(), // iKey/oKey
744 anyInt(), // mask
745 eq(tunnelResourceId));
746 }
747
748 ipSecConfig.setXfrmInterfaceId(tunnelResourceId);
749 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
750 }
751
Benedict Wong963502f2019-10-03 11:09:00 -0700752
753 @Test
754 public void testApplyTunnelModeTransformWithClosedSpi() throws Exception {
755 IpSecConfig ipSecConfig = new IpSecConfig();
756 ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
757 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
758 addAuthAndCryptToIpSecConfig(ipSecConfig);
759
760 IpSecTransformResponse createTransformResp =
761 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
762 IpSecTunnelInterfaceResponse createTunnelResp =
763 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
764
765 // Close SPI record
766 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
767
768 int transformResourceId = createTransformResp.resourceId;
769 int tunnelResourceId = createTunnelResp.resourceId;
770 mIpSecService.applyTunnelModeTransform(tunnelResourceId, IpSecManager.DIRECTION_OUT,
771 transformResourceId, "blessedPackage");
772
773 for (int selAddrFamily : ADDRESS_FAMILIES) {
774 verify(mMockNetd)
775 .ipSecUpdateSecurityPolicy(
776 eq(mUid),
777 eq(selAddrFamily),
778 eq(IpSecManager.DIRECTION_OUT),
779 anyString(),
780 anyString(),
781 eq(TEST_SPI),
782 anyInt(), // iKey/oKey
783 anyInt(), // mask
784 eq(tunnelResourceId));
785 }
786
787 ipSecConfig.setXfrmInterfaceId(tunnelResourceId);
788 verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
789 }
790
Benedict Wong781dae62018-09-06 11:31:25 -0700791 @Test
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800792 public void testAddRemoveAddressFromTunnelInterface() throws Exception {
Nathan Harold21208ee2018-03-15 18:06:06 -0700793 for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) {
794 IpSecTunnelInterfaceResponse createTunnelResp =
795 createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName);
796 mIpSecService.addAddressToTunnelInterface(
797 createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
798 verify(mMockNetd, times(1))
799 .interfaceAddAddress(
800 eq(createTunnelResp.interfaceName),
801 eq(mLocalInnerAddress.getAddress().getHostAddress()),
802 eq(mLocalInnerAddress.getPrefixLength()));
803 mIpSecService.removeAddressFromTunnelInterface(
804 createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
805 verify(mMockNetd, times(1))
806 .interfaceDelAddress(
807 eq(createTunnelResp.interfaceName),
808 eq(mLocalInnerAddress.getAddress().getHostAddress()),
809 eq(mLocalInnerAddress.getPrefixLength()));
810 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName);
811 }
812 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800813
Nathan Harold8c69bcb2018-05-15 19:18:38 -0700814 @Ignore
Nathan Harold21208ee2018-03-15 18:06:06 -0700815 @Test
816 public void testAddTunnelFailsForBadPackageName() throws Exception {
817 try {
818 IpSecTunnelInterfaceResponse createTunnelResp =
819 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "badPackage");
820 fail("Expected a SecurityException for badPackage.");
821 } catch (SecurityException expected) {
822 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800823 }
Benedict Wonge265d5f2018-11-08 19:45:34 -0800824
825 @Test
826 public void testFeatureFlagVerification() throws Exception {
827 when(mMockPkgMgr.hasSystemFeature(eq(PackageManager.FEATURE_IPSEC_TUNNELS)))
828 .thenReturn(false);
829
830 try {
831 String addr = Inet4Address.getLoopbackAddress().getHostAddress();
832 mIpSecService.createTunnelInterface(
833 addr, addr, new Network(0), new Binder(), "blessedPackage");
834 fail("Expected UnsupportedOperationException for disabled feature");
835 } catch (UnsupportedOperationException expected) {
836 }
837 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700838}