blob: 615cf62559f28492cc3ad3952f8041c566676bb1 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.ipsec.ike;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.net.InetAddresses;
import android.net.ipsec.ike.exceptions.InvalidSyntaxException;
import android.os.PersistableBundle;
import com.android.internal.net.TestUtils;
import org.junit.Test;
import java.net.InetAddress;
import java.nio.ByteBuffer;
public final class IkeTrafficSelectorTest {
private static final String TS_IPV4_ONE_HEX_STRING = "070000100010fff0c0000264c0000365";
private static final int TS_ONE_START_PORT = 16;
private static final int TS_ONE_END_PORT = 65520;
private static final InetAddress TS_ONE_START_ADDRESS =
InetAddresses.parseNumericAddress("192.0.2.100");
private static final InetAddress TS_ONE_END_ADDRESS =
InetAddresses.parseNumericAddress("192.0.3.101");
private static final String TS_IPV4_TWO_HEX_STRING = "070000100000ffffc0000464c0000466";
private static final int TS_TWO_START_PORT = 0;
private static final int TS_TWO_END_PORT = 65535;
private static final InetAddress TS_TWO_START_ADDRESS =
InetAddresses.parseNumericAddress("192.0.4.100");
private static final InetAddress TS_TWO_END_ADDRESS =
InetAddresses.parseNumericAddress("192.0.4.102");
private static final InetAddress TS_THREE_START_ADDRESS =
InetAddresses.parseNumericAddress("::");
private static final InetAddress TS_THREE_END_ADDRESS =
InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
String TS_IPV6_THREE_HEX_ADDRESS =
"080000280000ffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff";
private static final String TX_IPV4_INVALID_PORT_RANGE_HEX_STRING =
"0700001022221111c0000464c0000466";
private static final String TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING =
"070000100000ffffc0000466c0000366";
private static final int TS_TYPE_OFFSET = 0;
private static final int PROTOCOL_ID_OFFSET = 1;
private static final int TS_LENGTH_OFFSET = 2;
private IkeTrafficSelector mTsOne;
private IkeTrafficSelector mTsTwo;
private IkeTrafficSelector mTsIpv6Three;
public IkeTrafficSelectorTest() {
mTsOne =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
mTsTwo =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_TWO_START_PORT,
TS_TWO_END_PORT,
TS_TWO_START_ADDRESS,
TS_TWO_END_ADDRESS);
mTsIpv6Three =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE,
TS_TWO_START_PORT,
TS_TWO_END_PORT,
TS_THREE_START_ADDRESS,
TS_THREE_END_ADDRESS);
}
@Test
public void testDecodeIkeTrafficSelectors() throws Exception {
int numTs = 2;
byte[] tsBytes =
TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + TS_IPV4_TWO_HEX_STRING);
IkeTrafficSelector[] selectors =
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
assertEquals(numTs, selectors.length);
// Verify first traffic selector
IkeTrafficSelector tsOne = selectors[0];
assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsOne.tsType);
assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsOne.ipProtocolId);
assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsOne.selectorLength);
assertEquals(TS_ONE_START_PORT, tsOne.startPort);
assertEquals(TS_ONE_END_PORT, tsOne.endPort);
assertEquals(TS_ONE_START_ADDRESS, tsOne.startingAddress);
assertEquals(TS_ONE_END_ADDRESS, tsOne.endingAddress);
// Verify second traffic selector
IkeTrafficSelector tsTwo = selectors[1];
assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsTwo.tsType);
assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsTwo.ipProtocolId);
assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsTwo.selectorLength);
assertEquals(TS_TWO_START_PORT, tsTwo.startPort);
assertEquals(TS_TWO_END_PORT, tsTwo.endPort);
assertEquals(TS_TWO_START_ADDRESS, tsTwo.startingAddress);
assertEquals(TS_TWO_END_ADDRESS, tsTwo.endingAddress);
}
@Test
public void testBuildAndEncodeIkeTrafficSelector() throws Exception {
IkeTrafficSelector ts =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
ByteBuffer byteBuffer = ByteBuffer.allocate(ts.selectorLength);
ts.encodeToByteBuffer(byteBuffer);
byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
assertArrayEquals(expectedBytes, byteBuffer.array());
}
@Test
public void testEquals() throws Exception {
IkeTrafficSelector tsOneOther =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
assertEquals(mTsOne, tsOneOther);
assertNotEquals(mTsOne, mTsTwo);
}
@Test
public void testContains() throws Exception {
IkeTrafficSelector tsOneSubset =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT + 1,
TS_ONE_END_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
assertTrue(mTsOne.contains(tsOneSubset));
assertFalse(tsOneSubset.contains(mTsOne));
assertTrue(mTsOne.contains(mTsOne));
assertFalse(mTsOne.contains(mTsTwo));
}
private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeTrafficSelector ts) {
PersistableBundle bundle = ts.toPersistableBundle();
IkeTrafficSelector resultTs = IkeTrafficSelector.fromPersistableBundle(bundle);
assertEquals(ts, resultTs);
}
@Test
public void testPersistableBundleEncodeDecodeIsLosslessIpv4Ts() throws Exception {
verifyPersistableBundleEncodeDecodeIsLossless(mTsOne);
}
@Test
public void testPersistableBundleEncodeDecodeIsLosslessIpv6Ts() throws Exception {
verifyPersistableBundleEncodeDecodeIsLossless(mTsIpv6Three);
}
@Test
public void testDecodeIkeTrafficSelectorWithInvalidTsType() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
tsBytes[TS_TYPE_OFFSET] = -1;
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail due to invalid Traffic Selector Type.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testDecodeIkeTrafficSelectorWithInvalidIpProtocol() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
tsBytes[PROTOCOL_ID_OFFSET] = -1;
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail due to invalid IP Protocol ID.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testDecodeIkeTrafficSelectorWithExpectedTrailing() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + "FFFF");
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail due to unexpected trailing characters.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testDecodeIkeTrafficSelectorWithInvalidTsLength() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
// Traffic Selector field is two octets
tsBytes[TS_LENGTH_OFFSET] = 0;
tsBytes[TS_LENGTH_OFFSET + 1] = 0;
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail due to invalid Traffic Selector length.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testDecodeIkeTrafficSelectorWithInvalidPortRange() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_PORT_RANGE_HEX_STRING);
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail when start port is larger than end port.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testDecodeIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING);
try {
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail when starting address is larger than ending address.");
} catch (InvalidSyntaxException expected) {
}
}
@Test
public void testBuildIkeTrafficSelectorWithInvalidTsType() throws Exception {
try {
IkeTrafficSelector ts =
new IkeTrafficSelector(
0,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
fail("Expected to fail due to unrecognized Traffic Selector type.");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testBuildIkeTrafficSelectorWithInvalidPortRange() throws Exception {
try {
IkeTrafficSelector ts =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_END_PORT,
TS_ONE_START_PORT,
TS_ONE_START_ADDRESS,
TS_ONE_END_ADDRESS);
fail("Expected to fail due to invalid port range.");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testBuildIkeTrafficSelectorWithMismatchedAddressType() throws Exception {
InetAddress inet6Address = InetAddresses.parseNumericAddress("0:2001:0:db8::1");
try {
IkeTrafficSelector ts =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
inet6Address,
TS_ONE_END_ADDRESS);
fail("Expected to fail due to mismatched address format.");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testBuildIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
try {
IkeTrafficSelector ts =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_ONE_END_ADDRESS,
TS_ONE_START_ADDRESS);
fail("Expected to fail due to invalid address range.");
} catch (IllegalArgumentException e) {
}
}
@Test
public void testBuildAndEncodeIpv6TrafficSelector() throws Exception {
ByteBuffer byteBuffer = ByteBuffer.allocate(mTsIpv6Three.selectorLength);
mTsIpv6Three.encodeToByteBuffer(byteBuffer);
byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_IPV6_THREE_HEX_ADDRESS);
assertArrayEquals(expectedBytes, byteBuffer.array());
}
@Test
public void testIpv6TsEquals() throws Exception {
IkeTrafficSelector tsThreeOther =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE,
TS_TWO_START_PORT,
TS_TWO_END_PORT,
TS_THREE_START_ADDRESS,
TS_THREE_END_ADDRESS);
IkeTrafficSelector tsThreeOtherDifferentPort =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_THREE_START_ADDRESS,
TS_THREE_END_ADDRESS);
assertEquals(mTsIpv6Three, tsThreeOther);
assertNotEquals(mTsIpv6Three, tsThreeOtherDifferentPort);
}
@Test
public void testIpv6TsContains() throws Exception {
IkeTrafficSelector tsIpv6ThreeSubsetPortRange =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE,
TS_ONE_START_PORT,
TS_ONE_END_PORT,
TS_THREE_START_ADDRESS,
TS_THREE_END_ADDRESS);
IkeTrafficSelector tsIpv6ThreeSubsetAddrRange =
new IkeTrafficSelector(
IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE,
TS_TWO_START_PORT,
TS_TWO_END_PORT,
TS_THREE_START_ADDRESS,
InetAddresses.parseNumericAddress(
"2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
assertTrue(mTsIpv6Three.contains(tsIpv6ThreeSubsetPortRange));
assertTrue(mTsIpv6Three.contains(tsIpv6ThreeSubsetAddrRange));
assertFalse(tsIpv6ThreeSubsetPortRange.contains(mTsIpv6Three));
assertFalse(tsIpv6ThreeSubsetAddrRange.contains(mTsIpv6Three));
}
@Test
public void testDecodeIpv6TS() throws Exception {
int numTs = 1;
byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV6_THREE_HEX_ADDRESS);
IkeTrafficSelector[] selectors =
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
assertEquals(numTs, selectors.length);
assertTrue(selectors[0].equals(mTsIpv6Three));
}
@Test
public void testDecodeWithBothIpv6AndIpv4TS() throws Exception {
int numTs = 2;
byte[] tsBytes =
TestUtils.hexStringToByteArray(TS_IPV6_THREE_HEX_ADDRESS + TS_IPV4_ONE_HEX_STRING);
IkeTrafficSelector[] selectors =
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
assertEquals(numTs, selectors.length);
assertTrue(selectors[0].equals(mTsIpv6Three));
assertTrue(selectors[1].equals(mTsOne));
}
@Test
public void testDecodeIpv6TSWithInvalidLength() throws Exception {
int numTs = 2;
byte[] tsBytes =
TestUtils.hexStringToByteArray(TS_IPV6_THREE_HEX_ADDRESS + "FFFF");
try {
IkeTrafficSelector[] selectors =
IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
fail("Expected to fail with invalid syntax exception");
} catch(InvalidSyntaxException e) {
}
}
}