Merge "Update IpSecManagerTest for API changes to Transforms"

This commit is contained in:
nharold
2018-01-17 08:40:37 +00:00
committed by Gerrit Code Review

View File

@@ -36,6 +36,7 @@ import android.test.AndroidTestCase;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@@ -61,7 +62,6 @@ public class IpSecManagerTest extends AndroidTestCase {
private static final InetAddress GOOGLE_DNS_4 = IpAddress("8.8.8.8"); private static final InetAddress GOOGLE_DNS_4 = IpAddress("8.8.8.8");
private static final InetAddress GOOGLE_DNS_6 = IpAddress("2001:4860:4860::8888"); private static final InetAddress GOOGLE_DNS_6 = IpAddress("2001:4860:4860::8888");
private static final InetAddress LOOPBACK_4 = IpAddress("127.0.0.1");
private static final InetAddress[] GOOGLE_DNS_LIST = private static final InetAddress[] GOOGLE_DNS_LIST =
new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6};
@@ -110,20 +110,17 @@ public class IpSecManagerTest extends AndroidTestCase {
public void testAllocSpi() throws Exception { public void testAllocSpi() throws Exception {
for (InetAddress addr : GOOGLE_DNS_LIST) { for (InetAddress addr : GOOGLE_DNS_LIST) {
IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null;
randomSpi = mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, addr); randomSpi = mISM.allocateSecurityParameterIndex(addr);
assertTrue( assertTrue(
"Failed to receive a valid SPI", "Failed to receive a valid SPI",
randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
droidSpi = droidSpi = mISM.allocateSecurityParameterIndex(addr, DROID_SPI);
mISM.allocateSecurityParameterIndex( assertTrue("Failed to allocate specified SPI, " + DROID_SPI,
IpSecTransform.DIRECTION_IN, addr, DROID_SPI);
assertTrue(
"Failed to allocate specified SPI, " + DROID_SPI,
droidSpi.getSpi() == DROID_SPI); droidSpi.getSpi() == DROID_SPI);
try { try {
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_IN, addr, DROID_SPI); mISM.allocateSecurityParameterIndex(addr, DROID_SPI);
fail("Duplicate SPI was allowed to be created"); fail("Duplicate SPI was allowed to be created");
} catch (IpSecManager.SpiUnavailableException expected) { } catch (IpSecManager.SpiUnavailableException expected) {
// This is a success case because we expect a dupe SPI to throw // This is a success case because we expect a dupe SPI to throw
@@ -197,7 +194,8 @@ public class IpSecManagerTest extends AndroidTestCase {
localPort = getPort(udpSocket); localPort = getPort(udpSocket);
} }
mISM.applyTransportModeTransform(udpSocket, transform); mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_OUT, transform);
for (int i = 0; i < sendCount; i++) { for (int i = 0; i < sendCount; i++) {
byte[] in = new byte[TEST_DATA.length]; byte[] in = new byte[TEST_DATA.length];
@@ -206,7 +204,7 @@ public class IpSecManagerTest extends AndroidTestCase {
assertArrayEquals("Encapsulated data did not match.", TEST_DATA, in); assertArrayEquals("Encapsulated data did not match.", TEST_DATA, in);
} }
mISM.removeTransportModeTransform(udpSocket, transform); mISM.removeTransportModeTransforms(udpSocket, transform);
Os.close(udpSocket); Os.close(udpSocket);
} }
@@ -236,14 +234,17 @@ public class IpSecManagerTest extends AndroidTestCase {
Os.bind(server, local, 0); Os.bind(server, local, 0);
int port = ((InetSocketAddress) Os.getsockname(server)).getPort(); int port = ((InetSocketAddress) Os.getsockname(server)).getPort();
mISM.applyTransportModeTransform(client, transform); mISM.applyTransportModeTransform(client, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(server, transform); mISM.applyTransportModeTransform(client, IpSecManager.DIRECTION_OUT, transform);
mISM.applyTransportModeTransform(server, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(server, IpSecManager.DIRECTION_OUT, transform);
Os.listen(server, 10); Os.listen(server, 10);
Os.connect(client, local, port); Os.connect(client, local, port);
FileDescriptor accepted = Os.accept(server, null); FileDescriptor accepted = Os.accept(server, null);
mISM.applyTransportModeTransform(accepted, transform); mISM.applyTransportModeTransform(accepted, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(accepted, IpSecManager.DIRECTION_OUT, transform);
// Wait for TCP handshake packets to be counted // Wait for TCP handshake packets to be counted
StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK) StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK)
@@ -271,9 +272,9 @@ public class IpSecManagerTest extends AndroidTestCase {
StatsChecker.waitForNumPackets(4 * (i + 1)); StatsChecker.waitForNumPackets(4 * (i + 1));
} }
mISM.removeTransportModeTransform(server, transform); mISM.removeTransportModeTransforms(server, transform);
mISM.removeTransportModeTransform(client, transform); mISM.removeTransportModeTransforms(client, transform);
mISM.removeTransportModeTransform(accepted, transform); mISM.removeTransportModeTransforms(accepted, transform);
Os.close(server); Os.close(server);
Os.close(client); Os.close(client);
@@ -291,37 +292,20 @@ public class IpSecManagerTest extends AndroidTestCase {
* send data (expect exception) * send data (expect exception)
*/ */
public void testCreateTransform() throws Exception { public void testCreateTransform() throws Exception {
InetAddress local = LOOPBACK_4; InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
IpSecManager.SecurityParameterIndex outSpi = IpSecManager.SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local); mISM.allocateSecurityParameterIndex(localAddr);
IpSecManager.SecurityParameterIndex inSpi =
mISM.allocateSecurityParameterIndex(
IpSecTransform.DIRECTION_IN, local, outSpi.getSpi());
IpSecTransform transform = IpSecTransform transform =
new IpSecTransform.Builder(mContext) new IpSecTransform.Builder(mContext)
.setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
.setEncryption( .setEncryption(
IpSecTransform.DIRECTION_OUT,
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
.setAuthentication( .setAuthentication(
IpSecTransform.DIRECTION_OUT,
new IpSecAlgorithm( new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_SHA256, IpSecAlgorithm.AUTH_HMAC_SHA256,
AUTH_KEY, AUTH_KEY,
AUTH_KEY.length * 8)) AUTH_KEY.length * 8))
.setSpi(IpSecTransform.DIRECTION_IN, inSpi) .buildTransportModeTransform(localAddr, spi);
.setEncryption(
IpSecTransform.DIRECTION_IN,
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
.setAuthentication(
IpSecTransform.DIRECTION_IN,
new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_SHA256,
AUTH_KEY,
CRYPT_KEY.length * 8))
.buildTransportModeTransform(local);
// Bind localSocket to a random available port. // Bind localSocket to a random available port.
DatagramSocket localSocket = new DatagramSocket(0); DatagramSocket localSocket = new DatagramSocket(0);
@@ -330,14 +314,16 @@ public class IpSecManagerTest extends AndroidTestCase {
ParcelFileDescriptor pin = ParcelFileDescriptor.fromDatagramSocket(localSocket); ParcelFileDescriptor pin = ParcelFileDescriptor.fromDatagramSocket(localSocket);
FileDescriptor udpSocket = pin.getFileDescriptor(); FileDescriptor udpSocket = pin.getFileDescriptor();
mISM.applyTransportModeTransform(udpSocket, transform); // TODO: test combinations of one-way transforms.
mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_OUT, transform);
byte[] data = new String("Best test data ever!").getBytes("UTF-8"); byte[] data = new String("Best test data ever!").getBytes("UTF-8");
byte[] in = new byte[data.length]; byte[] in = new byte[data.length];
Os.sendto(udpSocket, data, 0, data.length, 0, local, localPort); Os.sendto(udpSocket, data, 0, data.length, 0, localAddr, localPort);
Os.read(udpSocket, in, 0, in.length); Os.read(udpSocket, in, 0, in.length);
assertTrue("Encapsulated data did not match.", Arrays.equals(data, in)); assertTrue("Encapsulated data did not match.", Arrays.equals(data, in));
mISM.removeTransportModeTransform(udpSocket, transform); mISM.removeTransportModeTransforms(udpSocket, transform);
Os.close(udpSocket); Os.close(udpSocket);
transform.close(); transform.close();
} }
@@ -476,20 +462,13 @@ public class IpSecManagerTest extends AndroidTestCase {
InetAddress local = InetAddress.getByName(localAddress); InetAddress local = InetAddress.getByName(localAddress);
try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
IpSecManager.SecurityParameterIndex outSpi = IpSecManager.SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local); mISM.allocateSecurityParameterIndex(local)) {
IpSecManager.SecurityParameterIndex inSpi =
mISM.allocateSecurityParameterIndex(
IpSecTransform.DIRECTION_IN, local, outSpi.getSpi())) {
IpSecTransform.Builder transformBuilder = IpSecTransform.Builder transformBuilder =
new IpSecTransform.Builder(mContext) new IpSecTransform.Builder(mContext)
.setSpi(IpSecTransform.DIRECTION_OUT, outSpi) .setEncryption(crypt)
.setEncryption(IpSecTransform.DIRECTION_OUT, crypt) .setAuthentication(auth);
.setAuthentication(IpSecTransform.DIRECTION_OUT, auth)
.setSpi(IpSecTransform.DIRECTION_IN, inSpi)
.setEncryption(IpSecTransform.DIRECTION_IN, crypt)
.setAuthentication(IpSecTransform.DIRECTION_IN, auth);
if (doUdpEncap) { if (doUdpEncap) {
transformBuilder = transformBuilder =
@@ -500,7 +479,8 @@ public class IpSecManagerTest extends AndroidTestCase {
int transportHdrLen = 0; int transportHdrLen = 0;
int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0; int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0;
try (IpSecTransform transform = transformBuilder.buildTransportModeTransform(local)) { try (IpSecTransform transform =
transformBuilder.buildTransportModeTransform(local, spi)) {
if (protocol == IPPROTO_TCP) { if (protocol == IPPROTO_TCP) {
transportHdrLen = TCP_HDRLEN_WITH_OPTIONS; transportHdrLen = TCP_HDRLEN_WITH_OPTIONS;
checkTcp(transform, local, sendCount, useJavaSockets); checkTcp(transform, local, sendCount, useJavaSockets);
@@ -920,19 +900,16 @@ public class IpSecManagerTest extends AndroidTestCase {
} }
public void testUdpEncapsulation() throws Exception { public void testUdpEncapsulation() throws Exception {
InetAddress local = LOOPBACK_4; InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
// TODO: Refactor to make this more representative of a normal application use case. (use // TODO: Refactor to make this more representative of a normal application use case. (use
// separate sockets for inbound and outbound) // separate sockets for inbound and outbound)
// Create SPIs, UDP encap socket // Create SPIs, UDP encap socket
try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
IpSecManager.SecurityParameterIndex outSpi = IpSecManager.SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local); mISM.allocateSecurityParameterIndex(local);
IpSecManager.SecurityParameterIndex inSpi =
mISM.allocateSecurityParameterIndex(
IpSecTransform.DIRECTION_IN, local, outSpi.getSpi());
IpSecTransform transform = IpSecTransform transform =
buildIpSecTransform(mContext, inSpi, outSpi, encapSocket, local)) { buildIpSecTransform(mContext, spi, encapSocket, local)) {
// Create user socket, apply transform to it // Create user socket, apply transform to it
FileDescriptor udpSocket = null; FileDescriptor udpSocket = null;
@@ -940,7 +917,10 @@ public class IpSecManagerTest extends AndroidTestCase {
udpSocket = getBoundUdpSocket(local); udpSocket = getBoundUdpSocket(local);
int port = getPort(udpSocket); int port = getPort(udpSocket);
mISM.applyTransportModeTransform(udpSocket, transform); mISM.applyTransportModeTransform(
udpSocket, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(
udpSocket, IpSecManager.DIRECTION_OUT, transform);
// Send an ESP packet from this socket to itself. Since the inbound and // Send an ESP packet from this socket to itself. Since the inbound and
// outbound transforms match, we should receive the data we sent. // outbound transforms match, we should receive the data we sent.
@@ -970,7 +950,7 @@ public class IpSecManagerTest extends AndroidTestCase {
"Encap socket was unable to send/receive IKE data", "Encap socket was unable to send/receive IKE data",
Arrays.equals(data, in)); Arrays.equals(data, in));
mISM.removeTransportModeTransform(udpSocket, transform); mISM.removeTransportModeTransforms(udpSocket, transform);
} finally { } finally {
if (udpSocket != null) { if (udpSocket != null) {
Os.close(udpSocket); Os.close(udpSocket);
@@ -980,26 +960,25 @@ public class IpSecManagerTest extends AndroidTestCase {
} }
public void testIke() throws Exception { public void testIke() throws Exception {
InetAddress local = LOOPBACK_4; InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
// TODO: Refactor to make this more representative of a normal application use case. (use // TODO: Refactor to make this more representative of a normal application use case. (use
// separate sockets for inbound and outbound) // separate sockets for inbound and outbound)
try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
IpSecManager.SecurityParameterIndex outSpi = IpSecManager.SecurityParameterIndex spi =
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local); mISM.allocateSecurityParameterIndex(localAddr);
IpSecManager.SecurityParameterIndex inSpi =
mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_IN, local);
IpSecTransform transform = IpSecTransform transform =
buildIpSecTransform(mContext, inSpi, outSpi, encapSocket, local)) { buildIpSecTransform(mContext, spi, encapSocket, localAddr)) {
// Create user socket, apply transform to it // Create user socket, apply transform to it
FileDescriptor sock = null; FileDescriptor sock = null;
try { try {
sock = getBoundUdpSocket(local); sock = getBoundUdpSocket(localAddr);
int port = getPort(sock); int port = getPort(sock);
mISM.applyTransportModeTransform(sock, transform); mISM.applyTransportModeTransform(sock, IpSecManager.DIRECTION_IN, transform);
mISM.applyTransportModeTransform(sock, IpSecManager.DIRECTION_OUT, transform);
// TODO: Find a way to set a timeout on the socket, and assert the ESP packet // TODO: Find a way to set a timeout on the socket, and assert the ESP packet
// doesn't make it through. Setting sockopts currently throws EPERM (possibly // doesn't make it through. Setting sockopts currently throws EPERM (possibly
@@ -1010,7 +989,7 @@ public class IpSecManagerTest extends AndroidTestCase {
byte[] header = new byte[] {1, 1, 1, 1}; byte[] header = new byte[] {1, 1, 1, 1};
String message = "Sample ESP Packet"; String message = "Sample ESP Packet";
byte[] data = (new String(header) + message).getBytes("UTF-8"); byte[] data = (new String(header) + message).getBytes("UTF-8");
Os.sendto(sock, data, 0, data.length, 0, local, encapSocket.getPort()); Os.sendto(sock, data, 0, data.length, 0, localAddr, encapSocket.getPort());
// Send IKE packet from the encap socket to itself. Since IKE is not // Send IKE packet from the encap socket to itself. Since IKE is not
// transformed in any way, this should succeed. // transformed in any way, this should succeed.
@@ -1023,7 +1002,7 @@ public class IpSecManagerTest extends AndroidTestCase {
0, 0,
data.length, data.length,
0, 0,
local, localAddr,
encapSocket.getPort()); encapSocket.getPort());
// ESP data should be dropped, due to different input SPI (as opposed to being // ESP data should be dropped, due to different input SPI (as opposed to being
@@ -1038,7 +1017,7 @@ public class IpSecManagerTest extends AndroidTestCase {
"Encap socket received UDP-encap-ESP data despite invalid SPIs", "Encap socket received UDP-encap-ESP data despite invalid SPIs",
Arrays.equals(header, in)); Arrays.equals(header, in));
mISM.removeTransportModeTransform(sock, transform); mISM.removeTransportModeTransforms(sock, transform);
} finally { } finally {
if (sock != null) { if (sock != null) {
Os.close(sock); Os.close(sock);
@@ -1049,30 +1028,20 @@ public class IpSecManagerTest extends AndroidTestCase {
private static IpSecTransform buildIpSecTransform( private static IpSecTransform buildIpSecTransform(
Context mContext, Context mContext,
IpSecManager.SecurityParameterIndex inSpi, IpSecManager.SecurityParameterIndex spi,
IpSecManager.SecurityParameterIndex outSpi,
IpSecManager.UdpEncapsulationSocket encapSocket, IpSecManager.UdpEncapsulationSocket encapSocket,
InetAddress remoteAddr) InetAddress remoteAddr)
throws Exception { throws Exception {
String localAddr = (remoteAddr instanceof Inet4Address)
? IPV4_LOOPBACK : IPV6_LOOPBACK;
return new IpSecTransform.Builder(mContext) return new IpSecTransform.Builder(mContext)
.setSpi(IpSecTransform.DIRECTION_IN, inSpi)
.setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
.setEncryption( .setEncryption(
IpSecTransform.DIRECTION_IN,
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
.setEncryption(
IpSecTransform.DIRECTION_OUT,
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
.setAuthentication( .setAuthentication(
IpSecTransform.DIRECTION_IN,
new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4))
.setAuthentication(
IpSecTransform.DIRECTION_OUT,
new IpSecAlgorithm( new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4)) IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4))
.setIpv4Encapsulation(encapSocket, encapSocket.getPort()) .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
.buildTransportModeTransform(remoteAddr); .buildTransportModeTransform(InetAddress.getByName(localAddr), spi);
} }
private static int getPort(FileDescriptor sock) throws Exception { private static int getPort(FileDescriptor sock) throws Exception {