1 /*
2  * Copyright (C) 2019 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 
17 package android.net;
18 
19 import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS;
20 import static android.net.cts.util.IkeSessionTestUtils.IKE_PARAMS_V6;
21 import static android.net.cts.util.IkeSessionTestUtils.getTestIkeSessionParams;
22 
23 import static org.junit.Assert.assertArrayEquals;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29 
30 import android.net.ipsec.ike.IkeKeyIdIdentification;
31 import android.net.ipsec.ike.IkeTunnelConnectionParams;
32 
33 import androidx.test.ext.junit.runners.AndroidJUnit4;
34 import androidx.test.filters.SmallTest;
35 
36 import com.android.internal.net.VpnProfile;
37 import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator;
38 import com.android.net.module.util.ProxyUtils;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.math.BigInteger;
45 import java.security.KeyPair;
46 import java.security.KeyPairGenerator;
47 import java.security.PrivateKey;
48 import java.security.cert.X509Certificate;
49 import java.util.ArrayList;
50 import java.util.Arrays;
51 import java.util.Date;
52 import java.util.List;
53 import java.util.concurrent.TimeUnit;
54 
55 import javax.security.auth.x500.X500Principal;
56 
57 /** Unit tests for {@link Ikev2VpnProfile.Builder}. */
58 @SmallTest
59 @RunWith(AndroidJUnit4.class)
60 public class Ikev2VpnProfileTest {
61     private static final String SERVER_ADDR_STRING = "1.2.3.4";
62     private static final String IDENTITY_STRING = "Identity";
63     private static final String USERNAME_STRING = "username";
64     private static final String PASSWORD_STRING = "pa55w0rd";
65     private static final String EXCL_LIST = "exclList";
66     private static final byte[] PSK_BYTES = "preSharedKey".getBytes();
67     private static final int TEST_MTU = 1300;
68 
69     private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy(
70             SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST));
71 
72     private X509Certificate mUserCert;
73     private X509Certificate mServerRootCa;
74     private PrivateKey mPrivateKey;
75 
76     @Before
setUp()77     public void setUp() throws Exception {
78         mServerRootCa = generateRandomCertAndKeyPair().cert;
79 
80         final CertificateAndKey userCertKey = generateRandomCertAndKeyPair();
81         mUserCert = userCertKey.cert;
82         mPrivateKey = userCertKey.key;
83     }
84 
getBuilderWithDefaultOptions()85     private Ikev2VpnProfile.Builder getBuilderWithDefaultOptions() {
86         final Ikev2VpnProfile.Builder builder =
87                 new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING);
88 
89         builder.setBypassable(true);
90         builder.setProxy(mProxy);
91         builder.setMaxMtu(TEST_MTU);
92         builder.setMetered(true);
93 
94         return builder;
95     }
96 
97     @Test
testBuildValidProfileWithOptions()98     public void testBuildValidProfileWithOptions() throws Exception {
99         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
100 
101         builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
102         final Ikev2VpnProfile profile = builder.build();
103         assertNotNull(profile);
104 
105         // Check non-auth parameters correctly stored
106         assertEquals(SERVER_ADDR_STRING, profile.getServerAddr());
107         assertEquals(IDENTITY_STRING, profile.getUserIdentity());
108         assertEquals(mProxy, profile.getProxyInfo());
109         assertTrue(profile.isBypassable());
110         assertTrue(profile.isMetered());
111         assertEquals(TEST_MTU, profile.getMaxMtu());
112         assertEquals(Ikev2VpnProfile.DEFAULT_ALGORITHMS, profile.getAllowedAlgorithms());
113     }
114 
115     @Test
testBuildUsernamePasswordProfile()116     public void testBuildUsernamePasswordProfile() throws Exception {
117         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
118 
119         builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
120         final Ikev2VpnProfile profile = builder.build();
121         assertNotNull(profile);
122 
123         assertEquals(USERNAME_STRING, profile.getUsername());
124         assertEquals(PASSWORD_STRING, profile.getPassword());
125         assertEquals(mServerRootCa, profile.getServerRootCaCert());
126 
127         assertNull(profile.getPresharedKey());
128         assertNull(profile.getRsaPrivateKey());
129         assertNull(profile.getUserCert());
130     }
131 
132     @Test
testBuildDigitalSignatureProfile()133     public void testBuildDigitalSignatureProfile() throws Exception {
134         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
135 
136         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
137         final Ikev2VpnProfile profile = builder.build();
138         assertNotNull(profile);
139 
140         assertEquals(profile.getUserCert(), mUserCert);
141         assertEquals(mPrivateKey, profile.getRsaPrivateKey());
142         assertEquals(profile.getServerRootCaCert(), mServerRootCa);
143 
144         assertNull(profile.getPresharedKey());
145         assertNull(profile.getUsername());
146         assertNull(profile.getPassword());
147     }
148 
149     @Test
testBuildPresharedKeyProfile()150     public void testBuildPresharedKeyProfile() throws Exception {
151         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
152 
153         builder.setAuthPsk(PSK_BYTES);
154         final Ikev2VpnProfile profile = builder.build();
155         assertNotNull(profile);
156 
157         assertArrayEquals(PSK_BYTES, profile.getPresharedKey());
158 
159         assertNull(profile.getServerRootCaCert());
160         assertNull(profile.getUsername());
161         assertNull(profile.getPassword());
162         assertNull(profile.getRsaPrivateKey());
163         assertNull(profile.getUserCert());
164     }
165 
166     @Test
testBuildWithAllowedAlgorithmsAead()167     public void testBuildWithAllowedAlgorithmsAead() throws Exception {
168         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
169         builder.setAuthPsk(PSK_BYTES);
170 
171         List<String> allowedAlgorithms =
172                 Arrays.asList(
173                         IpSecAlgorithm.AUTH_CRYPT_AES_GCM,
174                         IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305);
175         builder.setAllowedAlgorithms(allowedAlgorithms);
176 
177         final Ikev2VpnProfile profile = builder.build();
178         assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
179     }
180 
181     @Test
testBuildWithAllowedAlgorithmsNormal()182     public void testBuildWithAllowedAlgorithmsNormal() throws Exception {
183         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
184         builder.setAuthPsk(PSK_BYTES);
185 
186         List<String> allowedAlgorithms =
187                 Arrays.asList(
188                         IpSecAlgorithm.AUTH_HMAC_SHA512,
189                         IpSecAlgorithm.AUTH_AES_XCBC,
190                         IpSecAlgorithm.AUTH_AES_CMAC,
191                         IpSecAlgorithm.CRYPT_AES_CBC,
192                         IpSecAlgorithm.CRYPT_AES_CTR);
193         builder.setAllowedAlgorithms(allowedAlgorithms);
194 
195         final Ikev2VpnProfile profile = builder.build();
196         assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
197     }
198 
199     @Test
testSetAllowedAlgorithmsEmptyList()200     public void testSetAllowedAlgorithmsEmptyList() throws Exception {
201         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
202 
203         try {
204             builder.setAllowedAlgorithms(new ArrayList<>());
205             fail("Expected exception due to no valid algorithm set");
206         } catch (IllegalArgumentException expected) {
207         }
208     }
209 
210     @Test
testSetAllowedAlgorithmsInvalidList()211     public void testSetAllowedAlgorithmsInvalidList() throws Exception {
212         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
213 
214         try {
215             builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA256));
216             fail("Expected exception due to missing encryption");
217         } catch (IllegalArgumentException expected) {
218         }
219 
220         try {
221             builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.CRYPT_AES_CBC));
222             fail("Expected exception due to missing authentication");
223         } catch (IllegalArgumentException expected) {
224         }
225     }
226 
227     @Test
testSetAllowedAlgorithmsInsecureAlgorithm()228     public void testSetAllowedAlgorithmsInsecureAlgorithm() throws Exception {
229         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
230 
231         try {
232             builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_MD5));
233             fail("Expected exception due to insecure algorithm");
234         } catch (IllegalArgumentException expected) {
235         }
236 
237         try {
238             builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA1));
239             fail("Expected exception due to insecure algorithm");
240         } catch (IllegalArgumentException expected) {
241         }
242     }
243 
244     @Test
testBuildNoAuthMethodSet()245     public void testBuildNoAuthMethodSet() throws Exception {
246         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
247 
248         try {
249             builder.build();
250             fail("Expected exception due to lack of auth method");
251         } catch (IllegalArgumentException expected) {
252         }
253     }
254 
255     @Test
testBuildExcludeLocalRoutesSet()256     public void testBuildExcludeLocalRoutesSet() throws Exception {
257         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
258         builder.setAuthPsk(PSK_BYTES);
259         builder.setLocalRoutesExcluded(true);
260 
261         final Ikev2VpnProfile profile = builder.build();
262         assertNotNull(profile);
263         assertTrue(profile.areLocalRoutesExcluded());
264 
265         builder.setBypassable(false);
266         try {
267             builder.build();
268             fail("Expected exception because excludeLocalRoutes should be set only"
269                     + " on the bypassable VPN");
270         } catch (IllegalArgumentException expected) {
271         }
272     }
273 
274     @Test
testBuildInvalidMtu()275     public void testBuildInvalidMtu() throws Exception {
276         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
277 
278         try {
279             builder.setMaxMtu(500);
280             fail("Expected exception due to too-small MTU");
281         } catch (IllegalArgumentException expected) {
282         }
283     }
284 
verifyVpnProfileCommon(VpnProfile profile)285     private void verifyVpnProfileCommon(VpnProfile profile) {
286         assertEquals(SERVER_ADDR_STRING, profile.server);
287         assertEquals(IDENTITY_STRING, profile.ipsecIdentifier);
288         assertEquals(mProxy, profile.proxy);
289         assertTrue(profile.isBypassable);
290         assertTrue(profile.isMetered);
291         assertEquals(TEST_MTU, profile.maxMtu);
292     }
293 
294     @Test
testPskConvertToVpnProfile()295     public void testPskConvertToVpnProfile() throws Exception {
296         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
297 
298         builder.setAuthPsk(PSK_BYTES);
299         final VpnProfile profile = builder.build().toVpnProfile();
300 
301         verifyVpnProfileCommon(profile);
302         assertEquals(Ikev2VpnProfile.encodeForIpsecSecret(PSK_BYTES), profile.ipsecSecret);
303 
304         // Check nothing else is set
305         assertEquals("", profile.username);
306         assertEquals("", profile.password);
307         assertEquals("", profile.ipsecUserCert);
308         assertEquals("", profile.ipsecCaCert);
309     }
310 
311     @Test
testUsernamePasswordConvertToVpnProfile()312     public void testUsernamePasswordConvertToVpnProfile() throws Exception {
313         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
314 
315         builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
316         final VpnProfile profile = builder.build().toVpnProfile();
317 
318         verifyVpnProfileCommon(profile);
319         assertEquals(USERNAME_STRING, profile.username);
320         assertEquals(PASSWORD_STRING, profile.password);
321         assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert);
322 
323         // Check nothing else is set
324         assertEquals("", profile.ipsecUserCert);
325         assertEquals("", profile.ipsecSecret);
326     }
327 
328     @Test
testRsaConvertToVpnProfile()329     public void testRsaConvertToVpnProfile() throws Exception {
330         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
331 
332         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
333         final VpnProfile profile = builder.build().toVpnProfile();
334 
335         final String expectedSecret = Ikev2VpnProfile.PREFIX_INLINE
336                 + Ikev2VpnProfile.encodeForIpsecSecret(mPrivateKey.getEncoded());
337         verifyVpnProfileCommon(profile);
338         assertEquals(Ikev2VpnProfile.certificateToPemString(mUserCert), profile.ipsecUserCert);
339         assertEquals(
340                 expectedSecret,
341                 profile.ipsecSecret);
342         assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert);
343 
344         // Check nothing else is set
345         assertEquals("", profile.username);
346         assertEquals("", profile.password);
347     }
348 
349     @Test
testPskFromVpnProfileDiscardsIrrelevantValues()350     public void testPskFromVpnProfileDiscardsIrrelevantValues() throws Exception {
351         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
352 
353         builder.setAuthPsk(PSK_BYTES);
354         final VpnProfile profile = builder.build().toVpnProfile();
355         profile.username = USERNAME_STRING;
356         profile.password = PASSWORD_STRING;
357         profile.ipsecCaCert = Ikev2VpnProfile.certificateToPemString(mServerRootCa);
358         profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert);
359 
360         final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
361         assertNull(result.getUsername());
362         assertNull(result.getPassword());
363         assertNull(result.getUserCert());
364         assertNull(result.getRsaPrivateKey());
365         assertNull(result.getServerRootCaCert());
366     }
367 
368     @Test
testUsernamePasswordFromVpnProfileDiscardsIrrelevantValues()369     public void testUsernamePasswordFromVpnProfileDiscardsIrrelevantValues() throws Exception {
370         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
371 
372         builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
373         final VpnProfile profile = builder.build().toVpnProfile();
374         profile.ipsecSecret = new String(PSK_BYTES);
375         profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert);
376 
377         final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
378         assertNull(result.getPresharedKey());
379         assertNull(result.getUserCert());
380         assertNull(result.getRsaPrivateKey());
381     }
382 
383     @Test
testRsaFromVpnProfileDiscardsIrrelevantValues()384     public void testRsaFromVpnProfileDiscardsIrrelevantValues() throws Exception {
385         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
386 
387         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
388         final VpnProfile profile = builder.build().toVpnProfile();
389         profile.username = USERNAME_STRING;
390         profile.password = PASSWORD_STRING;
391 
392         final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
393         assertNull(result.getUsername());
394         assertNull(result.getPassword());
395         assertNull(result.getPresharedKey());
396     }
397 
398     @Test
testPskConversionIsLossless()399     public void testPskConversionIsLossless() throws Exception {
400         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
401 
402         builder.setAuthPsk(PSK_BYTES);
403         final Ikev2VpnProfile ikeProfile = builder.build();
404 
405         assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
406     }
407 
408     @Test
testUsernamePasswordConversionIsLossless()409     public void testUsernamePasswordConversionIsLossless() throws Exception {
410         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
411 
412         builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
413         final Ikev2VpnProfile ikeProfile = builder.build();
414 
415         assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
416     }
417 
418     @Test
testRsaConversionIsLossless()419     public void testRsaConversionIsLossless() throws Exception {
420         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
421 
422         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
423         final Ikev2VpnProfile ikeProfile = builder.build();
424 
425         assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
426     }
427 
428     @Test
testBuildWithIkeTunConnParamsConvertToVpnProfile()429     public void testBuildWithIkeTunConnParamsConvertToVpnProfile() throws Exception {
430         // Special keyId that contains delimiter character of VpnProfile
431         final byte[] keyId = "foo\0bar".getBytes();
432         final IkeTunnelConnectionParams tunnelParams = new IkeTunnelConnectionParams(
433                 getTestIkeSessionParams(true /* testIpv6 */, new IkeKeyIdIdentification(keyId)),
434                 CHILD_PARAMS);
435         final Ikev2VpnProfile ikev2VpnProfile = new Ikev2VpnProfile.Builder(tunnelParams).build();
436         final VpnProfile vpnProfile = ikev2VpnProfile.toVpnProfile();
437 
438         assertEquals(VpnProfile.TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS, vpnProfile.type);
439 
440         // Username, password, server, ipsecIdentifier, ipsecCaCert, ipsecSecret, ipsecUserCert and
441         // getAllowedAlgorithms should not be set if IkeTunnelConnectionParams is set.
442         assertEquals("", vpnProfile.server);
443         assertEquals("", vpnProfile.ipsecIdentifier);
444         assertEquals("", vpnProfile.username);
445         assertEquals("", vpnProfile.password);
446         assertEquals("", vpnProfile.ipsecCaCert);
447         assertEquals("", vpnProfile.ipsecSecret);
448         assertEquals("", vpnProfile.ipsecUserCert);
449         assertEquals(0, vpnProfile.getAllowedAlgorithms().size());
450 
451         // IkeTunnelConnectionParams should stay the same.
452         assertEquals(tunnelParams, vpnProfile.ikeTunConnParams);
453 
454         // Convert to disk-stable format and then back to Ikev2VpnProfile should be the same.
455         final VpnProfile decodedVpnProfile =
456                 VpnProfile.decode(vpnProfile.key, vpnProfile.encode());
457         final Ikev2VpnProfile convertedIkev2VpnProfile =
458                 Ikev2VpnProfile.fromVpnProfile(decodedVpnProfile);
459         assertEquals(ikev2VpnProfile, convertedIkev2VpnProfile);
460     }
461 
462     @Test
testConversionIsLosslessWithIkeTunConnParams()463     public void testConversionIsLosslessWithIkeTunConnParams() throws Exception {
464         final IkeTunnelConnectionParams tunnelParams =
465                 new IkeTunnelConnectionParams(IKE_PARAMS_V6, CHILD_PARAMS);
466         // Config authentication related fields is not required while building with
467         // IkeTunnelConnectionParams.
468         final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams).build();
469         assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
470     }
471 
472     @Test
testAutomaticNattAndIpVersionConversionIsLossless()473     public void testAutomaticNattAndIpVersionConversionIsLossless() throws Exception {
474         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
475         builder.setAutomaticNattKeepaliveTimerEnabled(true);
476         builder.setAutomaticIpVersionSelectionEnabled(true);
477 
478         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
479         final Ikev2VpnProfile ikeProfile = builder.build();
480 
481         assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
482     }
483 
484     @Test
testAutomaticNattAndIpVersionDefaults()485     public void testAutomaticNattAndIpVersionDefaults() throws Exception {
486         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
487 
488         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
489         final Ikev2VpnProfile ikeProfile = builder.build();
490 
491         assertEquals(false, ikeProfile.isAutomaticNattKeepaliveTimerEnabled());
492         assertEquals(false, ikeProfile.isAutomaticIpVersionSelectionEnabled());
493     }
494 
495     @Test
testEquals()496     public void testEquals() throws Exception {
497         // Verify building without IkeTunnelConnectionParams
498         final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
499         builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
500         assertEquals(builder.build(), builder.build());
501 
502         // Verify building with IkeTunnelConnectionParams
503         final IkeTunnelConnectionParams tunnelParams =
504                 new IkeTunnelConnectionParams(IKE_PARAMS_V6, CHILD_PARAMS);
505         final IkeTunnelConnectionParams tunnelParams2 =
506                 new IkeTunnelConnectionParams(IKE_PARAMS_V6, CHILD_PARAMS);
507         assertEquals(new Ikev2VpnProfile.Builder(tunnelParams).build(),
508                 new Ikev2VpnProfile.Builder(tunnelParams2).build());
509     }
510 
511     @Test
testBuildProfileWithNullProxy()512     public void testBuildProfileWithNullProxy() throws Exception {
513         final Ikev2VpnProfile ikev2VpnProfile =
514                 new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING)
515                         .setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa)
516                         .build();
517 
518         // ProxyInfo should be null for the profile without setting ProxyInfo.
519         assertNull(ikev2VpnProfile.getProxyInfo());
520 
521         // ProxyInfo should stay null after performing toVpnProfile() and fromVpnProfile()
522         final VpnProfile vpnProfile = ikev2VpnProfile.toVpnProfile();
523         assertNull(vpnProfile.proxy);
524 
525         final Ikev2VpnProfile convertedIkev2VpnProfile = Ikev2VpnProfile.fromVpnProfile(vpnProfile);
526         assertNull(convertedIkev2VpnProfile.getProxyInfo());
527     }
528 
529     private static class CertificateAndKey {
530         public final X509Certificate cert;
531         public final PrivateKey key;
532 
CertificateAndKey(X509Certificate cert, PrivateKey key)533         CertificateAndKey(X509Certificate cert, PrivateKey key) {
534             this.cert = cert;
535             this.key = key;
536         }
537     }
538 
generateRandomCertAndKeyPair()539     private static CertificateAndKey generateRandomCertAndKeyPair() throws Exception {
540         final Date validityBeginDate =
541                 new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1L));
542         final Date validityEndDate =
543                 new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1L));
544 
545         // Generate a keypair
546         final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
547         keyPairGenerator.initialize(512);
548         final KeyPair keyPair = keyPairGenerator.generateKeyPair();
549 
550         final X500Principal dnName = new X500Principal("CN=test.android.com");
551         final X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
552         certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
553         certGen.setSubjectDN(dnName);
554         certGen.setIssuerDN(dnName);
555         certGen.setNotBefore(validityBeginDate);
556         certGen.setNotAfter(validityEndDate);
557         certGen.setPublicKey(keyPair.getPublic());
558         certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
559 
560         final X509Certificate cert = certGen.generate(keyPair.getPrivate(), "AndroidOpenSSL");
561         return new CertificateAndKey(cert, keyPair.getPrivate());
562     }
563 }
564