diff options
-rw-r--r-- | core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java | 98 | ||||
-rw-r--r-- | tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java | 21 |
2 files changed, 117 insertions, 2 deletions
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java index 7f0c3280ea37..f54cc03bd695 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java +++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java @@ -16,22 +16,31 @@ package android.net.vcn.persistablebundleutils; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + import static com.android.internal.annotations.VisibleForTesting.Visibility; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.net.InetAddresses; import android.net.eap.EapSessionConfig; import android.net.ipsec.ike.IkeSaProposal; import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer; import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest; import android.os.PersistableBundle; import com.android.internal.annotations.VisibleForTesting; import com.android.server.vcn.util.PersistableBundleUtils; +import java.net.InetAddress; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; @@ -53,6 +62,7 @@ public final class IkeSessionParamsUtils { private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY"; private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY"; private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY"; + private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY"; private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY"; private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY"; private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY"; @@ -89,13 +99,21 @@ public final class IkeSessionParamsUtils { result.putPersistableBundle( REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig())); + final List<ConfigRequest> reqList = new ArrayList<>(); + for (IkeConfigRequest req : params.getConfigurationRequests()) { + reqList.add(new ConfigRequest(req)); + } + final PersistableBundle configReqListBundle = + PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle); + result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle); + result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis()); result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds()); result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds()); result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds()); result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds()); - // TODO: Handle configuration requests and IKE options. + // TODO: Handle IKE options. return result; } @@ -136,7 +154,33 @@ public final class IkeSessionParamsUtils { builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY)); builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY)); - // TODO: Handle configuration requests and IKE options. + final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY); + Objects.requireNonNull(configReqListBundle, "Config request list was null"); + final List<ConfigRequest> reqList = + PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new); + for (ConfigRequest req : reqList) { + switch (req.type) { + case ConfigRequest.IPV4_P_CSCF_ADDRESS: + if (req.address == null) { + builder.addPcscfServerRequest(AF_INET); + } else { + builder.addPcscfServerRequest(req.address); + } + break; + case ConfigRequest.IPV6_P_CSCF_ADDRESS: + if (req.address == null) { + builder.addPcscfServerRequest(AF_INET6); + } else { + builder.addPcscfServerRequest(req.address); + } + break; + default: + throw new IllegalArgumentException( + "Unrecognized config request type: " + req.type); + } + } + + // TODO: Handle IKE options. return builder.build(); } @@ -389,4 +433,54 @@ public final class IkeSessionParamsUtils { builder.setAuthEap(serverCaCert, eapConfig); } } + + private static final class ConfigRequest { + private static final int IPV4_P_CSCF_ADDRESS = 1; + private static final int IPV6_P_CSCF_ADDRESS = 2; + + private static final String TYPE_KEY = "type"; + private static final String ADDRESS_KEY = "address"; + + public final int type; + + // Null when it is an empty request + @Nullable public final InetAddress address; + + ConfigRequest(IkeConfigRequest config) { + if (config instanceof ConfigRequestIpv4PcscfServer) { + type = IPV4_P_CSCF_ADDRESS; + address = ((ConfigRequestIpv4PcscfServer) config).getAddress(); + } else if (config instanceof ConfigRequestIpv6PcscfServer) { + type = IPV6_P_CSCF_ADDRESS; + address = ((ConfigRequestIpv6PcscfServer) config).getAddress(); + } else { + throw new IllegalStateException("Unknown TunnelModeChildConfigRequest"); + } + } + + ConfigRequest(PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle was null"); + + type = in.getInt(TYPE_KEY); + + String addressStr = in.getString(ADDRESS_KEY); + if (addressStr == null) { + address = null; + } else { + address = InetAddresses.parseNumericAddress(addressStr); + } + } + + @NonNull + public PersistableBundle toPersistableBundle() { + final PersistableBundle result = new PersistableBundle(); + + result.putInt(TYPE_KEY, type); + if (address != null) { + result.putString(ADDRESS_KEY, address.getHostAddress()); + } + + return result; + } + } } diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java index 720d44a5b6fb..625f52c7b054 100644 --- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java +++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java @@ -16,6 +16,8 @@ package android.net.vcn.persistablebundleutils; +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.assertEquals; @@ -38,6 +40,8 @@ import org.junit.runner.RunWith; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.security.cert.CertificateFactory; @@ -104,6 +108,23 @@ public class IkeSessionParamsUtilsTest { } @Test + public void testEncodeRecodeParamsWithConfigRequests() throws Exception { + final Inet4Address ipv4Address = + (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.100"); + final Inet6Address ipv6Address = + (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1"); + + final IkeSessionParams params = + createBuilderMinimum() + .addPcscfServerRequest(AF_INET) + .addPcscfServerRequest(AF_INET6) + .addPcscfServerRequest(ipv4Address) + .addPcscfServerRequest(ipv6Address) + .build(); + verifyPersistableBundleEncodeDecodeIsLossless(params); + } + + @Test public void testEncodeRecodeParamsWithAuthPsk() throws Exception { final IkeSessionParams params = createBuilderMinimum().setAuthPsk("psk".getBytes()).build(); verifyPersistableBundleEncodeDecodeIsLossless(params); |