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