Refactor testCreateTransform and add IPv6 and encap coverage.
Currently, testCreateTransform only tests IPv4 transport mode.
Add support for IPv6 transport mode and IPv4 transport mode with
UDP encap.
Also use a try-with-resources to free the SPI and the transform
instead of relying on explicit close() calls. This requires
factoring out the code that creates the transform to a helper
method because try-with-resources blocks can only contain
assignments and not code.
Bug: 259001350
Test: atest CtsNetTestCasesLatestSdk:android.net.cts.IpSecManagerTest
Change-Id: I96107996ea0ac573460d0242d82c6706df192d24
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
index 8234ec1..4791eab 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -16,6 +16,7 @@
package android.net.cts;
+import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.net.IpSecAlgorithm.AUTH_AES_CMAC;
import static android.net.IpSecAlgorithm.AUTH_AES_XCBC;
import static android.net.IpSecAlgorithm.AUTH_CRYPT_AES_GCM;
@@ -53,6 +54,7 @@
import static com.android.compatibility.common.util.PropertyUtil.getFirstApiLevel;
import static com.android.compatibility.common.util.PropertyUtil.getVendorApiLevel;
import static com.android.testutils.MiscAsserts.assertThrows;
+import static com.android.testutils.TestPermissionUtil.runAsShell;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -62,6 +64,8 @@
import android.net.IpSecAlgorithm;
import android.net.IpSecManager;
+import android.net.IpSecManager.SecurityParameterIndex;
+import android.net.IpSecManager.UdpEncapsulationSocket;
import android.net.IpSecTransform;
import android.net.TrafficStats;
import android.os.Build;
@@ -120,7 +124,7 @@
@Test
public void testAllocSpi() throws Exception {
for (InetAddress addr : GOOGLE_DNS_LIST) {
- IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null;
+ SecurityParameterIndex randomSpi = null, droidSpi = null;
randomSpi = mISM.allocateSecurityParameterIndex(addr);
assertTrue(
"Failed to receive a valid SPI",
@@ -258,6 +262,24 @@
accepted.close();
}
+ private IpSecTransform buildTransportModeTransform(
+ SecurityParameterIndex spi, InetAddress localAddr,
+ UdpEncapsulationSocket encapSocket)
+ throws Exception {
+ final IpSecTransform.Builder builder =
+ new IpSecTransform.Builder(InstrumentationRegistry.getContext())
+ .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+ .setAuthentication(
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_HMAC_SHA256,
+ AUTH_KEY,
+ AUTH_KEY.length * 8));
+ if (encapSocket != null) {
+ builder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
+ }
+ return builder.buildTransportModeTransform(localAddr, spi);
+ }
+
/*
* Alloc outbound SPI
* Alloc inbound SPI
@@ -268,21 +290,8 @@
* release transform
* send data (expect exception)
*/
- @Test
- public void testCreateTransform() throws Exception {
- InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
- IpSecManager.SecurityParameterIndex spi =
- mISM.allocateSecurityParameterIndex(localAddr);
-
- IpSecTransform transform =
- new IpSecTransform.Builder(InstrumentationRegistry.getContext())
- .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
- .setAuthentication(
- new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256,
- AUTH_KEY,
- AUTH_KEY.length * 8))
- .buildTransportModeTransform(localAddr, spi);
+ private void doTestCreateTransform(String loopbackAddrString, boolean encap) throws Exception {
+ InetAddress localAddr = InetAddress.getByName(loopbackAddrString);
final boolean [][] applyInApplyOut = {
{false, false}, {false, true}, {true, false}, {true,true}};
@@ -291,50 +300,81 @@
byte[] in = new byte[data.length];
DatagramPacket inPacket = new DatagramPacket(in, in.length);
- DatagramSocket localSocket;
int localPort;
for(boolean[] io : applyInApplyOut) {
boolean applyIn = io[0];
boolean applyOut = io[1];
- // Bind localSocket to a random available port.
- localSocket = new DatagramSocket(0);
- localPort = localSocket.getLocalPort();
- localSocket.setSoTimeout(200);
- outPacket.setPort(localPort);
- if (applyIn) {
- mISM.applyTransportModeTransform(
- localSocket, IpSecManager.DIRECTION_IN, transform);
- }
- if (applyOut) {
- mISM.applyTransportModeTransform(
- localSocket, IpSecManager.DIRECTION_OUT, transform);
- }
- if (applyIn == applyOut) {
- localSocket.send(outPacket);
- localSocket.receive(inPacket);
- assertTrue("Encapsulated data did not match.",
- Arrays.equals(outPacket.getData(), inPacket.getData()));
- mISM.removeTransportModeTransforms(localSocket);
- localSocket.close();
- } else {
- try {
+ try (
+ SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(localAddr);
+ UdpEncapsulationSocket encapSocket = encap
+ ? getPrivilegedUdpEncapSocket(/*ipv6=*/ localAddr instanceof Inet6Address)
+ : null;
+ IpSecTransform transform = buildTransportModeTransform(spi, localAddr,
+ encapSocket);
+ // Bind localSocket to a random available port.
+ DatagramSocket localSocket = new DatagramSocket(0);
+ ) {
+ localPort = localSocket.getLocalPort();
+ localSocket.setSoTimeout(200);
+ outPacket.setPort(localPort);
+ if (applyIn) {
+ mISM.applyTransportModeTransform(
+ localSocket, IpSecManager.DIRECTION_IN, transform);
+ }
+ if (applyOut) {
+ mISM.applyTransportModeTransform(
+ localSocket, IpSecManager.DIRECTION_OUT, transform);
+ }
+ if (applyIn == applyOut) {
localSocket.send(outPacket);
localSocket.receive(inPacket);
- } catch (IOException e) {
- continue;
- } finally {
+ assertTrue("Encrypted data did not match.",
+ Arrays.equals(outPacket.getData(), inPacket.getData()));
mISM.removeTransportModeTransforms(localSocket);
- localSocket.close();
+ } else {
+ try {
+ localSocket.send(outPacket);
+ localSocket.receive(inPacket);
+ } catch (IOException e) {
+ continue;
+ } finally {
+ mISM.removeTransportModeTransforms(localSocket);
+ }
+ // FIXME: This check is disabled because sockets currently receive data
+ // if there is a valid SA for decryption, even when the input policy is
+ // not applied to a socket.
+ // fail("Data IO should fail on asymmetrical transforms! + Input="
+ // + applyIn + " Output=" + applyOut);
}
- // FIXME: This check is disabled because sockets currently receive data
- // if there is a valid SA for decryption, even when the input policy is
- // not applied to a socket.
- // fail("Data IO should fail on asymmetrical transforms! + Input="
- // + applyIn + " Output=" + applyOut);
}
}
- transform.close();
+ }
+
+ private UdpEncapsulationSocket getPrivilegedUdpEncapSocket(boolean ipv6) throws Exception {
+ return runAsShell(NETWORK_SETTINGS, () -> {
+ if (ipv6) {
+ return mISM.openUdpEncapsulationSocket(65536);
+ } else {
+ // Can't pass 0 to IpSecManager#openUdpEncapsulationSocket(int).
+ return mISM.openUdpEncapsulationSocket();
+ }
+ });
+ }
+
+ @Test
+ public void testCreateTransformIpv4() throws Exception {
+ doTestCreateTransform(IPV4_LOOPBACK, false);
+ }
+
+ @Test
+ public void testCreateTransformIpv6() throws Exception {
+ doTestCreateTransform(IPV6_LOOPBACK, false);
+ }
+
+ @Test
+ public void testCreateTransformIpv4Encap() throws Exception {
+ doTestCreateTransform(IPV4_LOOPBACK, true);
}
/** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */
@@ -503,8 +543,8 @@
StatsChecker.initStatsChecker();
InetAddress local = InetAddress.getByName(localAddress);
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
- IpSecManager.SecurityParameterIndex spi =
+ try (UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
+ SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(local)) {
IpSecTransform.Builder transformBuilder =
@@ -656,7 +696,7 @@
public void testIkeOverUdpEncapSocket() throws Exception {
// IPv6 not supported for UDP-encap-ESP
InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+ try (UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
NativeUdpSocket wrappedEncapSocket =
new NativeUdpSocket(encapSocket.getFileDescriptor());
checkIkePacket(wrappedEncapSocket, local);
@@ -665,7 +705,7 @@
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
- try (IpSecManager.SecurityParameterIndex spi =
+ try (SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(local);
IpSecTransform transform =
new IpSecTransform.Builder(InstrumentationRegistry.getContext())
@@ -1498,7 +1538,7 @@
@Test
public void testOpenUdpEncapSocketSpecificPort() throws Exception {
- IpSecManager.UdpEncapsulationSocket encapSocket = null;
+ UdpEncapsulationSocket encapSocket = null;
int port = -1;
for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) {
try {
@@ -1527,7 +1567,7 @@
@Test
public void testOpenUdpEncapSocketRandomPort() throws Exception {
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+ try (UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
assertTrue("Returned invalid port", encapSocket.getPort() != 0);
}
}