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.eap.test;
18 
19 import static android.net.eap.test.EapSessionConfig.EapMethodConfig.EAP_TYPE_AKA;
20 import static android.net.eap.test.EapSessionConfig.EapMethodConfig.EAP_TYPE_AKA_PRIME;
21 import static android.net.eap.test.EapSessionConfig.EapMethodConfig.EAP_TYPE_MSCHAP_V2;
22 import static android.net.eap.test.EapSessionConfig.EapMethodConfig.EAP_TYPE_SIM;
23 import static android.net.eap.test.EapSessionConfig.EapMethodConfig.EAP_TYPE_TTLS;
24 import static android.telephony.TelephonyManager.APPTYPE_USIM;
25 
26 import static org.junit.Assert.assertArrayEquals;
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertNotEquals;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.fail;
31 
32 import android.net.eap.test.EapSessionConfig.EapAkaConfig;
33 import android.net.eap.test.EapSessionConfig.EapAkaPrimeConfig;
34 import android.net.eap.test.EapSessionConfig.EapMethodConfig;
35 import android.net.eap.test.EapSessionConfig.EapMsChapV2Config;
36 import android.net.eap.test.EapSessionConfig.EapSimConfig;
37 import android.net.eap.test.EapSessionConfig.EapTtlsConfig;
38 import android.os.PersistableBundle;
39 
40 import com.android.internal.net.ipsec.test.ike.testutils.CertUtils;
41 
42 import org.junit.Test;
43 
44 import java.nio.charset.StandardCharsets;
45 import java.security.cert.X509Certificate;
46 
47 public class EapSessionConfigTest {
48     private static final byte[] DEFAULT_IDENTITY = new byte[0];
49     private static final byte[] EAP_IDENTITY =
50             "test@android.net".getBytes(StandardCharsets.US_ASCII);
51     private static final int SUB_ID = 1;
52     private static final String NETWORK_NAME = "android.net";
53     private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = true;
54     private static final String USERNAME = "username";
55     private static final String PASSWORD = "password";
56 
verifyPersistableBundleEncodeDecodeIsLossless(EapMethodConfig config)57     private static void verifyPersistableBundleEncodeDecodeIsLossless(EapMethodConfig config) {
58         PersistableBundle bundle = config.toPersistableBundle();
59         EapMethodConfig resultConfig = EapMethodConfig.fromPersistableBundle(bundle);
60 
61         assertEquals(config, resultConfig);
62     }
63 
verifyPersistableBundleEncodeDecodeIsLossless(EapSessionConfig config)64     private static void verifyPersistableBundleEncodeDecodeIsLossless(EapSessionConfig config) {
65         PersistableBundle bundle = config.toPersistableBundle();
66         EapSessionConfig resultConfig = EapSessionConfig.fromPersistableBundle(bundle);
67 
68         assertEquals(config, resultConfig);
69     }
70 
71     @Test
testBuildEapSim()72     public void testBuildEapSim() {
73         EapSessionConfig result = new EapSessionConfig.Builder()
74                 .setEapIdentity(EAP_IDENTITY)
75                 .setEapSimConfig(SUB_ID, APPTYPE_USIM)
76                 .build();
77 
78         assertArrayEquals(EAP_IDENTITY, result.getEapIdentity());
79 
80         EapMethodConfig eapMethodConfig = result.getEapConfigs().get(EAP_TYPE_SIM);
81         assertEquals(EAP_TYPE_SIM, eapMethodConfig.getMethodType());
82         EapSimConfig eapSimConfig = (EapSimConfig) eapMethodConfig;
83         assertEquals(SUB_ID, eapSimConfig.getSubId());
84         assertEquals(APPTYPE_USIM, eapSimConfig.getAppType());
85     }
86 
87     @Test
testPersistableBundleEncodeDecodeEapSim()88     public void testPersistableBundleEncodeDecodeEapSim() throws Exception {
89         verifyPersistableBundleEncodeDecodeIsLossless(new EapSimConfig(SUB_ID, APPTYPE_USIM));
90     }
91 
92     @Test
testBuildEapAka()93     public void testBuildEapAka() {
94         EapSessionConfig result = new EapSessionConfig.Builder()
95                 .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
96                 .build();
97 
98         assertArrayEquals(DEFAULT_IDENTITY, result.getEapIdentity());
99         EapMethodConfig eapMethodConfig = result.getEapConfigs().get(EAP_TYPE_AKA);
100         assertEquals(EAP_TYPE_AKA, eapMethodConfig.getMethodType());
101         EapAkaConfig eapAkaConfig = (EapAkaConfig) eapMethodConfig;
102         assertEquals(SUB_ID, eapAkaConfig.getSubId());
103         assertEquals(APPTYPE_USIM, eapAkaConfig.getAppType());
104     }
105 
106     @Test
testPersistableBundleEncodeDecodeEapAka()107     public void testPersistableBundleEncodeDecodeEapAka() throws Exception {
108         verifyPersistableBundleEncodeDecodeIsLossless(new EapAkaConfig(SUB_ID, APPTYPE_USIM));
109     }
110 
111     @Test
testBuildEapAkaPrime()112     public void testBuildEapAkaPrime() {
113         EapSessionConfig result =
114                 new EapSessionConfig.Builder()
115                         .setEapAkaPrimeConfig(
116                                 SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
117                         .build();
118 
119         assertArrayEquals(DEFAULT_IDENTITY, result.getEapIdentity());
120         EapMethodConfig eapMethodConfig = result.getEapConfigs().get(EAP_TYPE_AKA_PRIME);
121         assertEquals(EAP_TYPE_AKA_PRIME, eapMethodConfig.getMethodType());
122         EapAkaPrimeConfig eapAkaPrimeConfig = (EapAkaPrimeConfig) eapMethodConfig;
123         assertEquals(SUB_ID, eapAkaPrimeConfig.getSubId());
124         assertEquals(APPTYPE_USIM, eapAkaPrimeConfig.getAppType());
125         assertEquals(NETWORK_NAME, eapAkaPrimeConfig.getNetworkName());
126         assertTrue(eapAkaPrimeConfig.allowsMismatchedNetworkNames());
127     }
128 
129     @Test
testPersistableBundleEncodeDecodeEapAkaPrime()130     public void testPersistableBundleEncodeDecodeEapAkaPrime() throws Exception {
131         verifyPersistableBundleEncodeDecodeIsLossless(
132                 new EapAkaPrimeConfig(
133                         SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES));
134     }
135 
136     @Test
testBuildEapMsChapV2()137     public void testBuildEapMsChapV2() {
138         EapSessionConfig result =
139                 new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
140 
141         EapMsChapV2Config config =
142                 (EapMsChapV2Config) result.getEapConfigs().get(EAP_TYPE_MSCHAP_V2);
143         assertEquals(EAP_TYPE_MSCHAP_V2, config.getMethodType());
144         assertEquals(USERNAME, config.getUsername());
145         assertEquals(PASSWORD, config.getPassword());
146     }
147 
148     @Test
testPersistableBundleEncodeDecodeEapMsChapV2()149     public void testPersistableBundleEncodeDecodeEapMsChapV2() throws Exception {
150         verifyPersistableBundleEncodeDecodeIsLossless(new EapMsChapV2Config(USERNAME, PASSWORD));
151     }
152 
153     @Test
testBuildEapTtls()154     public void testBuildEapTtls() throws Exception {
155         EapSessionConfig innerConfig =
156                 new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
157         X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
158 
159         EapSessionConfig result =
160                 new EapSessionConfig.Builder().setEapTtlsConfig(trustedCa, innerConfig).build();
161 
162         assertArrayEquals(DEFAULT_IDENTITY, result.getEapIdentity());
163         EapTtlsConfig config = (EapTtlsConfig) result.getEapConfigs().get(EAP_TYPE_TTLS);
164         assertEquals(EAP_TYPE_TTLS, config.getMethodType());
165         assertEquals(innerConfig, config.getInnerEapSessionConfig());
166         assertEquals(trustedCa, config.getServerCaCert());
167     }
168 
169     @Test
testEqualsEapTtls()170     public void testEqualsEapTtls() throws Exception {
171         EapSessionConfig innerConfig =
172                 new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
173         X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
174 
175         assertEquals(
176                 new EapTtlsConfig(trustedCa, innerConfig),
177                 new EapTtlsConfig(trustedCa, innerConfig));
178         assertEquals(new EapTtlsConfig(null, innerConfig), new EapTtlsConfig(null, innerConfig));
179         assertNotEquals(
180                 new EapTtlsConfig(trustedCa, innerConfig), new EapTtlsConfig(null, innerConfig));
181     }
182 
183     @Test
testPersistableBundleEncodeDecodeEapTtls()184     public void testPersistableBundleEncodeDecodeEapTtls() throws Exception {
185         EapSessionConfig innerConfig =
186                 new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
187         X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
188 
189         verifyPersistableBundleEncodeDecodeIsLossless(new EapTtlsConfig(trustedCa, innerConfig));
190     }
191 
192     @Test(expected = NullPointerException.class)
testSetEapIdentityNull()193     public void testSetEapIdentityNull() {
194         new EapSessionConfig.Builder().setEapIdentity(null);
195     }
196 
197     @Test(expected = NullPointerException.class)
testBuildEapAkaPrimeNullNetworkName()198     public void testBuildEapAkaPrimeNullNetworkName() {
199         new EapSessionConfig.Builder()
200                 .setEapAkaPrimeConfig(SUB_ID, APPTYPE_USIM, null, ALLOW_MISMATCHED_NETWORK_NAMES);
201     }
202 
203     @Test(expected = NullPointerException.class)
testBuildEapMsChapV2NullUsername()204     public void testBuildEapMsChapV2NullUsername() {
205         new EapSessionConfig.Builder().setEapMsChapV2Config(null, PASSWORD);
206     }
207 
208     @Test(expected = NullPointerException.class)
testBuildEapMsChapV2NullPassword()209     public void testBuildEapMsChapV2NullPassword() {
210         new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, null);
211     }
212 
213     @Test(expected = IllegalArgumentException.class)
testBuildEapTtls_invalidInnerConfig()214     public void testBuildEapTtls_invalidInnerConfig() throws Exception {
215         EapSessionConfig msChapConfig =
216                 new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
217         EapSessionConfig innerTtlsConfig =
218                 new EapSessionConfig.Builder()
219                         .setEapTtlsConfig(null /* trustedCa */, msChapConfig)
220                         .build();
221         X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
222 
223         EapSessionConfig result =
224                 new EapSessionConfig.Builder().setEapTtlsConfig(trustedCa, innerTtlsConfig).build();
225     }
226 
227     @Test(expected = NullPointerException.class)
testBuildEapTtls_missingInnerConfig()228     public void testBuildEapTtls_missingInnerConfig() throws Exception {
229         X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
230 
231         EapSessionConfig result =
232                 new EapSessionConfig.Builder().setEapTtlsConfig(trustedCa, null).build();
233     }
234 
235     @Test
testPersistableBundleEncodeDecodeEapSessioConfig()236     public void testPersistableBundleEncodeDecodeEapSessioConfig() throws Exception {
237         EapSessionConfig config =
238                 new EapSessionConfig.Builder()
239                         .setEapIdentity(EAP_IDENTITY)
240                         .setEapSimConfig(SUB_ID, APPTYPE_USIM)
241                         .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
242                         .setEapAkaPrimeConfig(
243                                 SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
244                         .setEapMsChapV2Config(USERNAME, PASSWORD)
245                         .build();
246 
247         verifyPersistableBundleEncodeDecodeIsLossless(config);
248     }
249 
250     @Test
testPersistableBundleEncodeDecodeEapSessioConfigWithoutId()251     public void testPersistableBundleEncodeDecodeEapSessioConfigWithoutId() throws Exception {
252         EapSessionConfig config =
253                 new EapSessionConfig.Builder()
254                         .setEapSimConfig(SUB_ID, APPTYPE_USIM)
255                         .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
256                         .setEapAkaPrimeConfig(
257                                 SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
258                         .setEapMsChapV2Config(USERNAME, PASSWORD)
259                         .build();
260 
261         verifyPersistableBundleEncodeDecodeIsLossless(config);
262     }
263 
264     @Test
testBuildWithoutConfigs()265     public void testBuildWithoutConfigs() {
266         try {
267             new EapSessionConfig.Builder().build();
268             fail("build() should throw an IllegalStateException if no EAP methods are configured");
269         } catch (IllegalStateException expected) {
270         }
271     }
272 }
273