blob: 5c031eb11372693fdf8df65e9f3e5de41ae63ced [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;
Benedict Wong0febe5e2017-08-22 21:42:33 -070025import static org.mockito.Matchers.isNull;
Nathan Harold2e9a5202017-09-26 11:44:23 -070026import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
30import android.content.Context;
31import android.net.INetd;
32import android.net.IpSecAlgorithm;
33import android.net.IpSecConfig;
34import android.net.IpSecManager;
35import android.net.IpSecSpiResponse;
36import android.net.IpSecTransform;
37import android.net.IpSecTransformResponse;
38import android.net.NetworkUtils;
39import android.os.Binder;
40import android.os.ParcelFileDescriptor;
41import android.support.test.filters.SmallTest;
Nathan Harold2e9a5202017-09-26 11:44:23 -070042
43import java.net.Socket;
44import java.util.Arrays;
45import java.util.Collection;
46
47import org.junit.Before;
48import org.junit.Test;
49import org.junit.runner.RunWith;
50import org.junit.runners.Parameterized;
51
52/** Unit tests for {@link IpSecService}. */
53@SmallTest
54@RunWith(Parameterized.class)
55public class IpSecServiceParameterizedTest {
56
Benedict Wong0febe5e2017-08-22 21:42:33 -070057 private static final int TEST_SPI_OUT = 0xD1201D;
58 private static final int TEST_SPI_IN = TEST_SPI_OUT + 1;
Nathan Harold2e9a5202017-09-26 11:44:23 -070059
60 private final String mRemoteAddr;
61
62 @Parameterized.Parameters
63 public static Collection ipSecConfigs() {
64 return Arrays.asList(new Object[][] {{"8.8.4.4"}, {"2601::10"}});
65 }
66
Benedict Wong4ebc2c52017-11-01 17:14:25 -070067 private static final byte[] AEAD_KEY = {
68 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
69 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
70 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
71 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
72 0x73, 0x61, 0x6C, 0x74
73 };
Nathan Harold2e9a5202017-09-26 11:44:23 -070074 private static final byte[] CRYPT_KEY = {
75 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
76 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
77 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
78 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
79 };
80 private static final byte[] AUTH_KEY = {
81 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
83 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
85 };
86
87 Context mMockContext;
88 INetd mMockNetd;
89 IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
90 IpSecService mIpSecService;
91
Benedict Wong0febe5e2017-08-22 21:42:33 -070092 private static final IpSecAlgorithm AUTH_ALGO =
93 new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
94 private static final IpSecAlgorithm CRYPT_ALGO =
95 new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
96 private static final IpSecAlgorithm AEAD_ALGO =
Benedict Wong4ebc2c52017-11-01 17:14:25 -070097 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
Benedict Wong0febe5e2017-08-22 21:42:33 -070098
99 private static final int[] DIRECTIONS =
100 new int[] {IpSecTransform.DIRECTION_IN, IpSecTransform.DIRECTION_OUT};
101
Nathan Harold2e9a5202017-09-26 11:44:23 -0700102 public IpSecServiceParameterizedTest(String remoteAddr) {
103 mRemoteAddr = remoteAddr;
104 }
105
106 @Before
107 public void setUp() throws Exception {
108 mMockContext = mock(Context.class);
109 mMockNetd = mock(INetd.class);
110 mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
111 mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
112
113 // Injecting mock netd
114 when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
115 }
116
117 @Test
118 public void testIpSecServiceReserveSpi() throws Exception {
119 when(mMockNetd.ipSecAllocateSpi(
120 anyInt(),
121 eq(IpSecTransform.DIRECTION_OUT),
122 anyString(),
123 eq(mRemoteAddr),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700124 eq(TEST_SPI_OUT)))
125 .thenReturn(TEST_SPI_OUT);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700126
127 IpSecSpiResponse spiResp =
128 mIpSecService.reserveSecurityParameterIndex(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700129 IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700130 assertEquals(IpSecManager.Status.OK, spiResp.status);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700131 assertEquals(TEST_SPI_OUT, spiResp.spi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700132 }
133
134 @Test
135 public void testReleaseSecurityParameterIndex() throws Exception {
136 when(mMockNetd.ipSecAllocateSpi(
137 anyInt(),
138 eq(IpSecTransform.DIRECTION_OUT),
139 anyString(),
140 eq(mRemoteAddr),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700141 eq(TEST_SPI_OUT)))
142 .thenReturn(TEST_SPI_OUT);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700143
144 IpSecSpiResponse spiResp =
145 mIpSecService.reserveSecurityParameterIndex(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700146 IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700147
148 mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
149
150 verify(mMockNetd)
151 .ipSecDeleteSecurityAssociation(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700152 eq(spiResp.resourceId),
153 anyInt(),
154 anyString(),
155 anyString(),
156 eq(TEST_SPI_OUT));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700157 }
158
Benedict Wong0febe5e2017-08-22 21:42:33 -0700159 private int getNewSpiResourceId(int direction, String remoteAddress, int returnSpi)
160 throws Exception {
Nathan Harold2e9a5202017-09-26 11:44:23 -0700161 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt()))
Benedict Wong0febe5e2017-08-22 21:42:33 -0700162 .thenReturn(returnSpi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700163
Benedict Wong0febe5e2017-08-22 21:42:33 -0700164 IpSecSpiResponse spi =
165 mIpSecService.reserveSecurityParameterIndex(
166 direction,
167 NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
168 IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
169 new Binder());
170 return spi.resourceId;
171 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700172
Benedict Wong0febe5e2017-08-22 21:42:33 -0700173 private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
174 config.setSpiResourceId(
175 IpSecTransform.DIRECTION_OUT,
176 getNewSpiResourceId(IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT));
177 config.setSpiResourceId(
178 IpSecTransform.DIRECTION_IN,
179 getNewSpiResourceId(IpSecTransform.DIRECTION_IN, mRemoteAddr, TEST_SPI_IN));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700180 config.setRemoteAddress(mRemoteAddr);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700181 }
182
183 private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
184 for (int direction : DIRECTIONS) {
185 config.setEncryption(direction, CRYPT_ALGO);
186 config.setAuthentication(direction, AUTH_ALGO);
187 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700188 }
189
190 @Test
191 public void testCreateTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700192 IpSecConfig ipSecConfig = new IpSecConfig();
193 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
194 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700195
196 IpSecTransformResponse createTransformResp =
197 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
198 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
199
200 verify(mMockNetd)
201 .ipSecAddSecurityAssociation(
202 eq(createTransformResp.resourceId),
203 anyInt(),
204 eq(IpSecTransform.DIRECTION_OUT),
205 anyString(),
206 anyString(),
207 anyLong(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700208 eq(TEST_SPI_OUT),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700209 eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
210 eq(AUTH_KEY),
211 anyInt(),
212 eq(IpSecAlgorithm.CRYPT_AES_CBC),
213 eq(CRYPT_KEY),
214 anyInt(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700215 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700216 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700217 eq(0),
218 anyInt(),
219 anyInt(),
220 anyInt());
221 verify(mMockNetd)
222 .ipSecAddSecurityAssociation(
223 eq(createTransformResp.resourceId),
224 anyInt(),
225 eq(IpSecTransform.DIRECTION_IN),
226 anyString(),
227 anyString(),
228 anyLong(),
229 eq(TEST_SPI_IN),
230 eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
231 eq(AUTH_KEY),
232 anyInt(),
233 eq(IpSecAlgorithm.CRYPT_AES_CBC),
234 eq(CRYPT_KEY),
235 anyInt(),
236 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700237 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700238 eq(0),
239 anyInt(),
240 anyInt(),
241 anyInt());
242 }
243
244 @Test
245 public void testCreateTransportModeTransformAead() throws Exception {
246 IpSecConfig ipSecConfig = new IpSecConfig();
247 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
248
249 ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_OUT, AEAD_ALGO);
250 ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_IN, AEAD_ALGO);
251
252 IpSecTransformResponse createTransformResp =
253 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
254 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
255
256 verify(mMockNetd)
257 .ipSecAddSecurityAssociation(
258 eq(createTransformResp.resourceId),
259 anyInt(),
260 eq(IpSecTransform.DIRECTION_OUT),
261 anyString(),
262 anyString(),
263 anyLong(),
264 eq(TEST_SPI_OUT),
265 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700266 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700267 eq(0),
268 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700269 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700270 eq(0),
271 eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700272 eq(AEAD_KEY),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700273 anyInt(),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700274 anyInt(),
275 anyInt(),
276 anyInt());
277 verify(mMockNetd)
278 .ipSecAddSecurityAssociation(
279 eq(createTransformResp.resourceId),
280 anyInt(),
281 eq(IpSecTransform.DIRECTION_IN),
282 anyString(),
283 anyString(),
284 anyLong(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700285 eq(TEST_SPI_IN),
286 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700287 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700288 eq(0),
289 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700290 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700291 eq(0),
292 eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700293 eq(AEAD_KEY),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700294 anyInt(),
295 anyInt(),
296 anyInt(),
297 anyInt());
298 }
299
300 @Test
Benedict Wong0febe5e2017-08-22 21:42:33 -0700301 public void testCreateInvalidConfigAeadWithAuth() throws Exception {
302 IpSecConfig ipSecConfig = new IpSecConfig();
303 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
304
305 for (int direction : DIRECTIONS) {
306 ipSecConfig.setAuthentication(direction, AUTH_ALGO);
307 ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
308 }
309
310 try {
311 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
312 fail(
313 "IpSecService should have thrown an error on authentication being"
314 + " enabled with authenticated encryption");
315 } catch (IllegalArgumentException expected) {
316 }
317 }
318
319 @Test
320 public void testCreateInvalidConfigAeadWithCrypt() throws Exception {
321 IpSecConfig ipSecConfig = new IpSecConfig();
322 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
323
324 for (int direction : DIRECTIONS) {
325 ipSecConfig.setEncryption(direction, CRYPT_ALGO);
326 ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
327 }
328
329 try {
330 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
331 fail(
332 "IpSecService should have thrown an error on encryption being"
333 + " enabled with authenticated encryption");
334 } catch (IllegalArgumentException expected) {
335 }
336 }
337
338 @Test
339 public void testCreateInvalidConfigAeadWithAuthAndCrypt() throws Exception {
340 IpSecConfig ipSecConfig = new IpSecConfig();
341 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
342
343 for (int direction : DIRECTIONS) {
344 ipSecConfig.setAuthentication(direction, AUTH_ALGO);
345 ipSecConfig.setEncryption(direction, CRYPT_ALGO);
346 ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
347 }
348
349 try {
350 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
351 fail(
352 "IpSecService should have thrown an error on authentication and encryption being"
353 + " enabled with authenticated encryption");
354 } catch (IllegalArgumentException expected) {
355 }
356 }
357
358 @Test
Nathan Harold2e9a5202017-09-26 11:44:23 -0700359 public void testDeleteTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700360 IpSecConfig ipSecConfig = new IpSecConfig();
361 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
362 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700363
364 IpSecTransformResponse createTransformResp =
365 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
366 mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId);
367
368 verify(mMockNetd)
369 .ipSecDeleteSecurityAssociation(
370 eq(createTransformResp.resourceId),
371 eq(IpSecTransform.DIRECTION_OUT),
372 anyString(),
373 anyString(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700374 eq(TEST_SPI_OUT));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700375 verify(mMockNetd)
376 .ipSecDeleteSecurityAssociation(
377 eq(createTransformResp.resourceId),
378 eq(IpSecTransform.DIRECTION_IN),
379 anyString(),
380 anyString(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700381 eq(TEST_SPI_IN));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700382 }
383
384 @Test
385 public void testApplyTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700386 IpSecConfig ipSecConfig = new IpSecConfig();
387 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
388 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700389
390 IpSecTransformResponse createTransformResp =
391 mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
392 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
393
394 int resourceId = createTransformResp.resourceId;
395 mIpSecService.applyTransportModeTransform(pfd, resourceId);
396
397 verify(mMockNetd)
398 .ipSecApplyTransportModeTransform(
399 eq(pfd.getFileDescriptor()),
400 eq(resourceId),
401 eq(IpSecTransform.DIRECTION_OUT),
402 anyString(),
403 anyString(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700404 eq(TEST_SPI_OUT));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700405 verify(mMockNetd)
406 .ipSecApplyTransportModeTransform(
407 eq(pfd.getFileDescriptor()),
408 eq(resourceId),
409 eq(IpSecTransform.DIRECTION_IN),
410 anyString(),
411 anyString(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700412 eq(TEST_SPI_IN));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700413 }
414
415 @Test
416 public void testRemoveTransportModeTransform() throws Exception {
417 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
418 mIpSecService.removeTransportModeTransform(pfd, 1);
419
420 verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
421 }
422}