blob: 86bbe2d5b06e6ef201a31e646732e6b51506da30 [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
19import static org.junit.Assert.assertEquals;
Benedict Wong0febe5e2017-08-22 21:42:33 -070020import static org.junit.Assert.fail;
Nathan Harold2e9a5202017-09-26 11:44:23 -070021import static org.mockito.Matchers.anyInt;
22import static org.mockito.Matchers.anyLong;
23import static org.mockito.Matchers.anyString;
24import static org.mockito.Matchers.eq;
25import static org.mockito.Mockito.mock;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.when;
28
29import android.content.Context;
30import android.net.INetd;
31import android.net.IpSecAlgorithm;
32import android.net.IpSecConfig;
33import android.net.IpSecManager;
34import android.net.IpSecSpiResponse;
Nathan Harold2e9a5202017-09-26 11:44:23 -070035import android.net.IpSecTransformResponse;
36import android.net.NetworkUtils;
37import android.os.Binder;
38import android.os.ParcelFileDescriptor;
39import android.support.test.filters.SmallTest;
Benedict Wong344bd622017-11-16 15:27:22 -080040import android.system.Os;
Nathan Harold2e9a5202017-09-26 11:44:23 -070041
42import java.net.Socket;
43import java.util.Arrays;
44import java.util.Collection;
45
46import org.junit.Before;
47import org.junit.Test;
48import org.junit.runner.RunWith;
49import org.junit.runners.Parameterized;
50
51/** Unit tests for {@link IpSecService}. */
52@SmallTest
53@RunWith(Parameterized.class)
54public class IpSecServiceParameterizedTest {
55
Nathan Harolda2523312018-01-05 19:25:13 -080056 private static final int TEST_SPI = 0xD1201D;
Nathan Harold2e9a5202017-09-26 11:44:23 -070057
Nathan Harolda2523312018-01-05 19:25:13 -080058 private final String mDestinationAddr;
Nathan Harold2e9a5202017-09-26 11:44:23 -070059
60 @Parameterized.Parameters
61 public static Collection ipSecConfigs() {
62 return Arrays.asList(new Object[][] {{"8.8.4.4"}, {"2601::10"}});
63 }
64
Benedict Wong4ebc2c52017-11-01 17:14:25 -070065 private static final byte[] AEAD_KEY = {
66 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
67 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
68 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
69 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
70 0x73, 0x61, 0x6C, 0x74
71 };
Nathan Harold2e9a5202017-09-26 11:44:23 -070072 private static final byte[] CRYPT_KEY = {
73 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
74 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
75 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
76 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
77 };
78 private static final byte[] AUTH_KEY = {
79 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
81 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
83 };
84
85 Context mMockContext;
86 INetd mMockNetd;
87 IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
88 IpSecService mIpSecService;
89
Benedict Wong0febe5e2017-08-22 21:42:33 -070090 private static final IpSecAlgorithm AUTH_ALGO =
91 new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
92 private static final IpSecAlgorithm CRYPT_ALGO =
93 new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
94 private static final IpSecAlgorithm AEAD_ALGO =
Benedict Wong4ebc2c52017-11-01 17:14:25 -070095 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
Benedict Wong0febe5e2017-08-22 21:42:33 -070096
Nathan Harold2e9a5202017-09-26 11:44:23 -070097 public IpSecServiceParameterizedTest(String remoteAddr) {
Nathan Harolda2523312018-01-05 19:25:13 -080098 mDestinationAddr = remoteAddr;
Nathan Harold2e9a5202017-09-26 11:44:23 -070099 }
100
101 @Before
102 public void setUp() throws Exception {
103 mMockContext = mock(Context.class);
104 mMockNetd = mock(INetd.class);
105 mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
106 mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
107
108 // Injecting mock netd
109 when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
110 }
111
112 @Test
113 public void testIpSecServiceReserveSpi() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800114 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
115 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700116
117 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800118 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800119 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700120 assertEquals(IpSecManager.Status.OK, spiResp.status);
Nathan Harolda2523312018-01-05 19:25:13 -0800121 assertEquals(TEST_SPI, spiResp.spi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700122 }
123
124 @Test
125 public void testReleaseSecurityParameterIndex() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800126 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
127 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700128
129 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800130 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800131 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700132
133 mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
134
135 verify(mMockNetd)
136 .ipSecDeleteSecurityAssociation(
Nathan Harolda2523312018-01-05 19:25:13 -0800137 eq(spiResp.resourceId), anyString(), anyString(), eq(TEST_SPI));
Benedict Wong344bd622017-11-16 15:27:22 -0800138
139 // Verify quota and RefcountedResource objects cleaned up
140 IpSecService.UserRecord userRecord =
141 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
142 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
143 try {
144 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
145 fail("Expected IllegalArgumentException on attempt to access deleted resource");
146 } catch (IllegalArgumentException expected) {
147
148 }
149 }
150
151 @Test
152 public void testSecurityParameterIndexBinderDeath() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800153 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
154 .thenReturn(TEST_SPI);
Benedict Wong344bd622017-11-16 15:27:22 -0800155
156 IpSecSpiResponse spiResp =
Nathan Harold660a3352017-12-14 14:46:46 -0800157 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800158 mDestinationAddr, TEST_SPI, new Binder());
Benedict Wong344bd622017-11-16 15:27:22 -0800159
160 IpSecService.UserRecord userRecord =
161 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
162 IpSecService.RefcountedResource refcountedRecord =
163 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
164
165 refcountedRecord.binderDied();
166
167 verify(mMockNetd)
168 .ipSecDeleteSecurityAssociation(
Nathan Harolda2523312018-01-05 19:25:13 -0800169 eq(spiResp.resourceId), anyString(), anyString(), eq(TEST_SPI));
Benedict Wong344bd622017-11-16 15:27:22 -0800170
171 // Verify quota and RefcountedResource objects cleaned up
172 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
173 try {
174 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
175 fail("Expected IllegalArgumentException on attempt to access deleted resource");
176 } catch (IllegalArgumentException expected) {
177
178 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700179 }
180
Nathan Harolda2523312018-01-05 19:25:13 -0800181 private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception {
182 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt()))
Benedict Wong0febe5e2017-08-22 21:42:33 -0700183 .thenReturn(returnSpi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700184
Benedict Wong0febe5e2017-08-22 21:42:33 -0700185 IpSecSpiResponse spi =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800186 mIpSecService.allocateSecurityParameterIndex(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700187 NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
188 IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
189 new Binder());
190 return spi.resourceId;
191 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700192
Benedict Wong0febe5e2017-08-22 21:42:33 -0700193 private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800194 config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI));
195 config.setDestinationAddress(mDestinationAddr);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700196 }
197
198 private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800199 config.setEncryption(CRYPT_ALGO);
200 config.setAuthentication(AUTH_ALGO);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700201 }
202
203 @Test
204 public void testCreateTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700205 IpSecConfig ipSecConfig = new IpSecConfig();
206 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
207 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700208
209 IpSecTransformResponse createTransformResp =
210 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
211 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
212
213 verify(mMockNetd)
214 .ipSecAddSecurityAssociation(
215 eq(createTransformResp.resourceId),
216 anyInt(),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700217 anyString(),
218 anyString(),
219 anyLong(),
Nathan Harolda2523312018-01-05 19:25:13 -0800220 eq(TEST_SPI),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700221 eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
222 eq(AUTH_KEY),
223 anyInt(),
224 eq(IpSecAlgorithm.CRYPT_AES_CBC),
225 eq(CRYPT_KEY),
226 anyInt(),
227 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700228 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700229 eq(0),
230 anyInt(),
231 anyInt(),
232 anyInt());
233 }
234
235 @Test
236 public void testCreateTransportModeTransformAead() throws Exception {
237 IpSecConfig ipSecConfig = new IpSecConfig();
238 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
239
Nathan Harolda2523312018-01-05 19:25:13 -0800240 ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700241
242 IpSecTransformResponse createTransformResp =
243 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
244 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
245
246 verify(mMockNetd)
247 .ipSecAddSecurityAssociation(
248 eq(createTransformResp.resourceId),
249 anyInt(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700250 anyString(),
251 anyString(),
252 anyLong(),
Nathan Harolda2523312018-01-05 19:25:13 -0800253 eq(TEST_SPI),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700254 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700255 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700256 eq(0),
257 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700258 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700259 eq(0),
260 eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700261 eq(AEAD_KEY),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700262 anyInt(),
263 anyInt(),
264 anyInt(),
265 anyInt());
266 }
267
268 @Test
269 public void testDeleteTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700270 IpSecConfig ipSecConfig = new IpSecConfig();
271 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
272 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700273
274 IpSecTransformResponse createTransformResp =
275 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
276 mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId);
277
278 verify(mMockNetd)
279 .ipSecDeleteSecurityAssociation(
Nathan Harolda2523312018-01-05 19:25:13 -0800280 eq(createTransformResp.resourceId), anyString(), anyString(), eq(TEST_SPI));
Benedict Wong344bd622017-11-16 15:27:22 -0800281
282 // Verify quota and RefcountedResource objects cleaned up
283 IpSecService.UserRecord userRecord =
284 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
285 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
286 try {
287 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
288 createTransformResp.resourceId);
289 fail("Expected IllegalArgumentException on attempt to access deleted resource");
290 } catch (IllegalArgumentException expected) {
291
292 }
293 }
294
295 @Test
296 public void testTransportModeTransformBinderDeath() throws Exception {
297 IpSecConfig ipSecConfig = new IpSecConfig();
298 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
299 addAuthAndCryptToIpSecConfig(ipSecConfig);
300
301 IpSecTransformResponse createTransformResp =
302 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
303
304 IpSecService.UserRecord userRecord =
305 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
306 IpSecService.RefcountedResource refcountedRecord =
307 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
308 createTransformResp.resourceId);
309
310 refcountedRecord.binderDied();
311
312 verify(mMockNetd)
313 .ipSecDeleteSecurityAssociation(
Nathan Harolda2523312018-01-05 19:25:13 -0800314 eq(createTransformResp.resourceId), anyString(), anyString(), eq(TEST_SPI));
Benedict Wong344bd622017-11-16 15:27:22 -0800315
316 // Verify quota and RefcountedResource objects cleaned up
317 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
318 try {
319 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
320 createTransformResp.resourceId);
321 fail("Expected IllegalArgumentException on attempt to access deleted resource");
322 } catch (IllegalArgumentException expected) {
323
324 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700325 }
326
327 @Test
328 public void testApplyTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700329 IpSecConfig ipSecConfig = new IpSecConfig();
330 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
331 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700332
333 IpSecTransformResponse createTransformResp =
334 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
335 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
336
337 int resourceId = createTransformResp.resourceId;
Nathan Harolda2523312018-01-05 19:25:13 -0800338 mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700339
340 verify(mMockNetd)
341 .ipSecApplyTransportModeTransform(
342 eq(pfd.getFileDescriptor()),
343 eq(resourceId),
Nathan Harolda2523312018-01-05 19:25:13 -0800344 eq(IpSecManager.DIRECTION_OUT),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700345 anyString(),
346 anyString(),
Nathan Harolda2523312018-01-05 19:25:13 -0800347 eq(TEST_SPI));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700348 }
349
350 @Test
351 public void testRemoveTransportModeTransform() throws Exception {
352 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
Nathan Harolda2523312018-01-05 19:25:13 -0800353 mIpSecService.removeTransportModeTransforms(pfd, 1);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700354
355 verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
356 }
357}