Merge "Test building IkeSessionParams with EAP"
diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp
index 8c073c9..f1f120b 100644
--- a/tests/cts/net/ipsec/Android.bp
+++ b/tests/cts/net/ipsec/Android.bp
@@ -26,6 +26,7 @@
 
     srcs: [
         "src/**/*.java",
+        ":ike-test-utils",
     ],
 
     static_libs: [
diff --git a/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem
new file mode 100644
index 0000000..972fd55
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSDCCAjCgAwIBAgIITJQJ6HC1rjwwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE
+BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h
+bmRyb2lkLm5ldDAeFw0xOTA5MzAxNzU1NTJaFw0yOTA5MjcxNzU1NTJaMEIxCzAJ
+BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSEwHwYDVQQDExhyb290LmNhLnRl
+c3QuYW5kcm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT
+q3hGF+JvLaB1xW7KGKmaxiQ7BxX2Sn7cbp7ggoVYXsFlBUuPPv3+Vg5PfPCPhsJ8
+/7w4HyKo3uc/vHs5HpQ7rSd9blhAkfmJci2ULLq73FB8Mix4CzPwMx29RrN1X9bU
+z4G0vJMczIBGxbZ0uw7n8bKcXBV7AIeax+J8lseEZ3k8iSuBkUJqGIpPFKTqByFZ
+A1Lvt47xkON5SZh6c/Oe+o6291wXaCOJUSAKv6PAWZkq9HeD2fqKA/ck9dBaz1M3
+YvzQ9V/7so3/dECjAfKia388h1I6XSGNUM+d5hpxMXpAFgG42eUXHpJ10OjDvSwd
+7ZSC91/kRQewUomEKBK1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBRJn6hHhdeDY/dXpCKUfrFYQhKAGjANBgkqhkiG
+9w0BAQsFAAOCAQEAig/94aGfHBhZuvbbhwAK4rUNpizmR567u0ZJ+QUEKyAlo9lT
+ZWYHSm7qTAZYvPEjzTQIptnAlxCHePXh3Cfwgo+r82lhG2rcdI03iRyvHWjM8gyk
+BXCJTi0Q08JHHpTP6GnAqpz58qEIFkk8P766zNXdhYrGPOydF+p7MFcb1Zv1gum3
+zmRLt0XUAMfjPUv1Bl8kTKFxH5lkMBLR1E0jnoJoTTfgRPrf9CuFSoh48n7YhoBT
+KV75xZY8b8+SuB0v6BvQmkpKZGoxBjuVsShyG7q1+4JTAtwhiP7BlkDvVkaBEi7t
+WIMFp2r2ZDisHgastNaeYFyzHYz9g1FCCrHQ4w==
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
index 91ef778..532be67 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
@@ -17,16 +17,22 @@
 package android.net.ipsec.ike.cts;
 
 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID;
+import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH;
 import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
 import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
+import android.net.eap.EapSessionConfig;
 import android.net.ipsec.ike.IkeFqdnIdentification;
 import android.net.ipsec.ike.IkeIdentification;
 import android.net.ipsec.ike.IkeSaProposal;
@@ -37,10 +43,14 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.net.ipsec.ike.testutils.CertUtils;
+
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.net.InetAddress;
+import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -76,6 +86,29 @@
     private static final IkeIdentification LOCAL_ID = new IkeFqdnIdentification(LOCAL_HOSTNAME);
     private static final IkeIdentification REMOTE_ID = new IkeFqdnIdentification(REMOTE_HOSTNAME);
 
+    private static final EapSessionConfig EAP_ALL_METHODS_CONFIG =
+            createEapOnlySafeMethodsBuilder()
+                    .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD)
+                    .build();
+    private static final EapSessionConfig EAP_ONLY_SAFE_METHODS_CONFIG =
+            createEapOnlySafeMethodsBuilder().build();
+
+    private X509Certificate mServerCaCert;
+
+    @Before
+    public void setUp() throws Exception {
+        mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem");
+    }
+
+    private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() {
+        return new EapSessionConfig.Builder()
+                .setEapIdentity(EAP_IDENTITY)
+                .setEapSimConfig(SUB_ID, APPTYPE_USIM)
+                .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
+                .setEapAkaPrimeConfig(
+                        SUB_ID, APPTYPE_USIM, NETWORK_NAME, true /* allowMismatchedNetworkNames */);
+    }
+
     /**
      * Create a Builder that has minimum configurations to build an IkeSessionParams.
      *
@@ -112,23 +145,6 @@
         assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk());
     }
 
-    private void verifySpecificPcscfConfigReqs(
-            HashSet<InetAddress> expectedAddresses, IkeSessionParams sessionParams) {
-        Set<InetAddress> resultAddresses = new HashSet<>();
-
-        for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) {
-            if (req instanceof ConfigRequestIpv4PcscfServer
-                    && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) {
-                resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress());
-            } else if (req instanceof ConfigRequestIpv6PcscfServer
-                    && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) {
-                resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress());
-            }
-        }
-
-        assertEquals(expectedAddresses, resultAddresses);
-    }
-
     @Test
     public void testBuildWithMinimumSet() throws Exception {
         IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build();
@@ -232,22 +248,39 @@
         assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID));
     }
 
-    @Test
-    public void testBuildWithPsk() throws Exception {
-        IkeSessionParams sessionParams =
-                new IkeSessionParams.Builder(sContext)
-                        .setNetwork(sTunNetwork)
-                        .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress())
-                        .addSaProposal(SA_PROPOSAL)
-                        .setLocalIdentification(LOCAL_ID)
-                        .setRemoteIdentification(REMOTE_ID)
-                        .setAuthPsk(IKE_PSK)
-                        .build();
+    /**
+     * Create a Builder that has minimum configurations to build an IkeSessionParams, except for
+     * authentication method.
+     */
+    private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() {
+        return new IkeSessionParams.Builder(sContext)
+                .setNetwork(sTunNetwork)
+                .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress())
+                .addSaProposal(SA_PROPOSAL)
+                .setLocalIdentification(LOCAL_ID)
+                .setRemoteIdentification(REMOTE_ID);
+    }
+
+    /**
+     * Verify the minimum configurations to build an IkeSessionParams, except for authentication
+     * method.
+     *
+     * @see #createIkeParamsBuilderMinimumWithoutAuth
+     */
+    private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) {
         assertEquals(sTunNetwork, sessionParams.getNetwork());
         assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname());
         assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals());
         assertEquals(LOCAL_ID, sessionParams.getLocalIdentification());
         assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification());
+    }
+
+    @Test
+    public void testBuildWithPsk() throws Exception {
+        IkeSessionParams sessionParams =
+                createIkeParamsBuilderMinimumWithoutAuth().setAuthPsk(IKE_PSK).build();
+
+        verifyIkeParamsMinimumWithoutAuth(sessionParams);
 
         IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
         assertTrue(localConfig instanceof IkeAuthPskConfig);
@@ -257,6 +290,57 @@
         assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk());
     }
 
-    // TODO(b/148689509): Add tests for building IkeSessionParams using EAP and
-    // digital-signature-based authentication
+    @Test
+    public void testBuildWithEap() throws Exception {
+        IkeSessionParams sessionParams =
+                createIkeParamsBuilderMinimumWithoutAuth()
+                        .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG)
+                        .build();
+
+        verifyIkeParamsMinimumWithoutAuth(sessionParams);
+
+        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
+        assertTrue(localConfig instanceof IkeAuthEapConfig);
+        assertEquals(EAP_ALL_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig());
+        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
+        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
+        assertEquals(
+                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
+    }
+
+    @Test
+    public void testBuildWithEapOnlyAuth() throws Exception {
+        IkeSessionParams sessionParams =
+                createIkeParamsBuilderMinimumWithoutAuth()
+                        .setAuthEap(mServerCaCert, EAP_ONLY_SAFE_METHODS_CONFIG)
+                        .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH)
+                        .build();
+
+        assertTrue(sessionParams.hasIkeOption(IKE_OPTION_EAP_ONLY_AUTH));
+        verifyIkeParamsMinimumWithoutAuth(sessionParams);
+
+        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
+        assertTrue(localConfig instanceof IkeAuthEapConfig);
+        assertEquals(EAP_ONLY_SAFE_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig());
+        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
+        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
+        assertEquals(
+                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
+    }
+
+    @Test
+    public void testThrowBuildEapOnlyAuthWithUnsafeMethod() throws Exception {
+        try {
+            IkeSessionParams sessionParams =
+                    createIkeParamsBuilderMinimumWithoutAuth()
+                            .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG)
+                            .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH)
+                            .build();
+            fail("Expected to fail because EAP only unsafe method is proposed");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    // TODO(b/148689509): Add tests for building IkeSessionParams using digital-signature-based
+    // authentication
 }
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
index 0847744..bc2bec6 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
@@ -49,6 +49,12 @@
     static final String LOCAL_RFC822_NAME = "client.test.ike@example.com";
     static final byte[] LOCAL_KEY_ID = "Local Key ID".getBytes();
 
+    static final int SUB_ID = 1;
+    static final byte[] EAP_IDENTITY = "test@android.net".getBytes();
+    static final String NETWORK_NAME = "android.net";
+    static final String EAP_MSCHAPV2_USERNAME = "username";
+    static final String EAP_MSCHAPV2_PASSWORD = "password";
+
     static final Inet4Address IPV4_ADDRESS_LOCAL =
             (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100"));
     static final Inet4Address IPV4_ADDRESS_REMOTE =