aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan Yan <evitayan@google.com>2019-03-26 15:12:54 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-03-26 15:12:54 -0700
commit2e52d6dd1afbfad17c30e1384e2c4d0913285ebf (patch)
treea8bf102d89dcb09807b08a2ceafdff2f4f903da4
parenta748e21a6a575264bed66de1b125f83e52f84ffd (diff)
parent10f5c63f720e7fa39733abfe90c52a05513bd605 (diff)
downloadike-2e52d6dd1afbfad17c30e1384e2c4d0913285ebf.tar.gz
Merge "Support IkeSessionOptions for basic IKE SA setup" am: 7a77ef4b33 am: 3a74cae3d5
am: 10f5c63f72 Change-Id: Idafef6686c9df53870babbd8af49e27ffc5011dd
-rw-r--r--src/java/com/android/ike/ikev2/IkeSessionOptions.java102
-rw-r--r--src/java/com/android/ike/ikev2/SaProposal.java2
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java103
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java26
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java4
5 files changed, 219 insertions, 18 deletions
diff --git a/src/java/com/android/ike/ikev2/IkeSessionOptions.java b/src/java/com/android/ike/ikev2/IkeSessionOptions.java
index 66ef94d6..fe06b85a 100644
--- a/src/java/com/android/ike/ikev2/IkeSessionOptions.java
+++ b/src/java/com/android/ike/ikev2/IkeSessionOptions.java
@@ -16,9 +16,107 @@
package com.android.ike.ikev2;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+
+import com.android.ike.ikev2.message.IkePayload;
+
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+
/**
- * IkeSessionOptions contains all configurations including cryptographic algorithm set of an IKE SA.
+ * IkeSessionOptions contains all user provided configurations for negotiating an IKE SA.
+ *
+ * <p>TODO: Make this doc more user-friendly.
*/
public class IkeSessionOptions {
- // TODO: Implement it.
+ private final InetAddress mServerAddress;
+ private final UdpEncapsulationSocket mUdpEncapSocket;
+ private final SaProposal[] mSaProposals;
+ private final boolean mIsIkeFragmentationSupported;
+
+ private IkeSessionOptions(
+ InetAddress serverAddress,
+ UdpEncapsulationSocket udpEncapsulationSocket,
+ SaProposal[] proposals,
+ boolean isIkeFragmentationSupported) {
+ mServerAddress = serverAddress;
+ mUdpEncapSocket = udpEncapsulationSocket;
+ mSaProposals = proposals;
+ mIsIkeFragmentationSupported = isIkeFragmentationSupported;
+ }
+
+ /** Package private */
+ InetAddress getServerAddress() {
+ return mServerAddress;
+ }
+ /** Package private */
+ UdpEncapsulationSocket getUdpEncapsulationSocket() {
+ return mUdpEncapSocket;
+ }
+ /** Package private */
+ SaProposal[] getSaProposals() {
+ return mSaProposals;
+ }
+ /** Package private */
+ boolean isIkeFragmentationSupported() {
+ return mIsIkeFragmentationSupported;
+ }
+
+ /** This class can be used to incrementally construct a IkeSessionOptions. */
+ public static final class Builder {
+ private final InetAddress mServerAddress;
+ private final UdpEncapsulationSocket mUdpEncapSocket;
+ private final List<SaProposal> mSaProposalList = new LinkedList<>();
+
+ private boolean mIsIkeFragmentationSupported = false;
+
+ /**
+ * Returns a new Builder for an IkeSessionOptions.
+ *
+ * @param serverAddress IP address of remote IKE server.
+ * @param udpEncapsulationSocket {@link IpSecManager.UdpEncapsulationSocket} for sending and
+ * receiving IKE message.
+ * @return Builder for an IkeSessionOptions.
+ */
+ public Builder(InetAddress serverAddress, UdpEncapsulationSocket udpEncapsulationSocket) {
+ mServerAddress = serverAddress;
+ mUdpEncapSocket = udpEncapsulationSocket;
+ }
+
+ /**
+ * Adds an IKE SA proposal to IkeSessionOptions being built.
+ *
+ * @param proposal IKE SA proposal.
+ * @return Builder for an IkeSessionOptions.
+ * @throws IllegalArgumentException if input proposal is not IKE SA proposal.
+ */
+ public Builder addSaProposal(SaProposal proposal) {
+ if (proposal.mProtocolId != IkePayload.PROTOCOL_ID_IKE) {
+ throw new IllegalArgumentException(
+ "Expected IKE SA Proposal but received Child SA proposal");
+ }
+ mSaProposalList.add(proposal);
+ return this;
+ }
+
+ /**
+ * Validates, builds and returns the IkeSessionOptions
+ *
+ * @return IkeSessionOptions the validated IkeSessionOptions
+ * @throws IllegalStateException if no IKE SA proposal is provided
+ */
+ public IkeSessionOptions build() {
+ if (mSaProposalList.isEmpty()) {
+ throw new IllegalArgumentException("IKE SA proposal not found");
+ }
+ return new IkeSessionOptions(
+ mServerAddress,
+ mUdpEncapSocket,
+ mSaProposalList.toArray(new SaProposal[mSaProposalList.size()]),
+ mIsIkeFragmentationSupported);
+ }
+
+ // TODO: add methods for supporting IKE fragmentation.
+ }
}
diff --git a/src/java/com/android/ike/ikev2/SaProposal.java b/src/java/com/android/ike/ikev2/SaProposal.java
index f932be24..3883404a 100644
--- a/src/java/com/android/ike/ikev2/SaProposal.java
+++ b/src/java/com/android/ike/ikev2/SaProposal.java
@@ -474,7 +474,7 @@ public final class SaProposal {
* @return SaProposal the validated SaProposal.
* @throws IllegalArgumentException if SaProposal is invalid.
*/
- public SaProposal buildOrThrow() {
+ public SaProposal build() {
EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow();
PrfTransform[] prfTransforms = buildPrfsOrThrow();
IntegrityTransform[] integrityTransforms =
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java
new file mode 100644
index 00000000..bdaf135a
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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 com.android.ike.ikev2;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.net.IpSecManager;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+
+import androidx.test.InstrumentationRegistry;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+
+public final class IkeSessionOptionsTest {
+ private static final Inet4Address IPV4_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+
+ private UdpEncapsulationSocket mUdpEncapSocket;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
+ mUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUdpEncapSocket.close();
+ }
+
+ @Test
+ public void testBuild() throws Exception {
+ SaProposal saProposal =
+ SaProposal.Builder.newIkeSaProposalBuilder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.KEY_LEN_AES_128)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+
+ IkeSessionOptions sessionOptions =
+ new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket)
+ .addSaProposal(saProposal)
+ .build();
+
+ assertEquals(IPV4_ADDRESS, sessionOptions.getServerAddress());
+ assertEquals(mUdpEncapSocket, sessionOptions.getUdpEncapsulationSocket());
+ assertArrayEquals(new SaProposal[] {saProposal}, sessionOptions.getSaProposals());
+ assertFalse(sessionOptions.isIkeFragmentationSupported());
+ }
+
+ @Test
+ public void testBuildWithoutSaProposal() throws Exception {
+ try {
+ new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket).build();
+ fail("Expected to fail due to absence of SA proposal.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testBuildWithChildSaProposal() throws Exception {
+ SaProposal saProposal =
+ SaProposal.Builder.newChildSaProposalBuilder(true)
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.KEY_LEN_AES_128)
+ .build();
+ try {
+ new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket)
+ .addSaProposal(saProposal)
+ .build();
+ fail("Expected to fail due to wrong type of SA proposal.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java b/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
index 2ce2a9d9..428c028d 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
@@ -64,7 +64,7 @@ public final class SaProposalTest {
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .buildOrThrow();
+ .build();
assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.mProtocolId);
assertArrayEquals(
@@ -87,7 +87,7 @@ public final class SaProposalTest {
SaProposal.KEY_LEN_AES_128)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .buildOrThrow();
+ .build();
assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.mProtocolId);
assertArrayEquals(
@@ -107,7 +107,7 @@ public final class SaProposalTest {
SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
SaProposal.KEY_LEN_AES_128)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
- .buildOrThrow();
+ .build();
assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.mProtocolId);
assertArrayEquals(
@@ -127,7 +127,7 @@ public final class SaProposalTest {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .buildOrThrow();
+ .build();
assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.mProtocolId);
assertArrayEquals(
@@ -143,7 +143,7 @@ public final class SaProposalTest {
public void testBuildEncryptAlgosWithNoAlgorithm() throws Exception {
Builder builder = Builder.newIkeSaProposalBuilder();
try {
- builder.buildOrThrow();
+ builder.build();
fail("Expected to fail when no encryption algorithm is proposed.");
} catch (IllegalArgumentException expected) {
@@ -179,7 +179,7 @@ public final class SaProposalTest {
public void testBuildIkeProposalWithoutPrf() throws Exception {
Builder builder = Builder.newIkeSaProposalBuilder();
try {
- builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES).buildOrThrow();
+ builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES).build();
fail("Expected to fail when PRF is not provided in IKE SA proposal.");
} catch (IllegalArgumentException expected) {
@@ -192,7 +192,7 @@ public final class SaProposalTest {
try {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
- .buildOrThrow();
+ .build();
fail("Expected to fail when PRF is provided in Child SA proposal.");
} catch (IllegalArgumentException expected) {
@@ -209,7 +209,7 @@ public final class SaProposalTest {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
- .buildOrThrow();
+ .build();
fail("Expected to fail when not-none integrity algorithm is proposed with AEAD");
} catch (IllegalArgumentException expected) {
@@ -225,7 +225,7 @@ public final class SaProposalTest {
try {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
- .buildOrThrow();
+ .build();
fail(
"Expected to fail when"
@@ -245,7 +245,7 @@ public final class SaProposalTest {
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
- .buildOrThrow();
+ .build();
fail(
"Expected to fail when none-value integrity algorithm is proposed"
@@ -262,7 +262,7 @@ public final class SaProposalTest {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
- .buildOrThrow();
+ .build();
fail("Expected to fail when no DH Group is proposed in IKE SA proposal.");
} catch (IllegalArgumentException expected) {
@@ -279,7 +279,7 @@ public final class SaProposalTest {
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
.addDhGroup(SaProposal.DH_GROUP_NONE)
- .buildOrThrow();
+ .build();
fail("Expected to fail when none-value DH Group is proposed in IKE SA proposal.");
} catch (IllegalArgumentException expected) {
@@ -295,7 +295,7 @@ public final class SaProposalTest {
builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .buildOrThrow();
+ .build();
fail(
"Expected to fail when"
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
index b0d927d8..2a47362c 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
@@ -153,7 +153,7 @@ public final class IkeSaPayloadTest {
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
- .buildOrThrow();
+ .build();
mSaProposalTwo =
SaProposal.Builder.newIkeSaProposalBuilder()
@@ -166,7 +166,7 @@ public final class IkeSaPayloadTest {
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
.addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
.addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP)
- .buildOrThrow();
+ .build();
mTwoSaProposalsArray = new SaProposal[] {mSaProposalOne, mSaProposalTwo};
}