Loading core/java/android/net/Ikev2VpnProfile.java +32 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,16 @@ package android.net; 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; import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; import static com.android.internal.annotations.VisibleForTesting.Visibility; import static com.android.internal.util.Preconditions.checkStringNotEmpty; import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; Loading Loading @@ -70,13 +80,28 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private static final String EMPTY_CERT = ""; /** @hide */ public static final List<String> DEFAULT_ALGORITHMS = Collections.unmodifiableList(Arrays.asList( IpSecAlgorithm.CRYPT_AES_CBC, IpSecAlgorithm.AUTH_HMAC_SHA256, IpSecAlgorithm.AUTH_HMAC_SHA384, IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.AUTH_CRYPT_AES_GCM)); public static final List<String> DEFAULT_ALGORITHMS; private static void addAlgorithmIfSupported(List<String> algorithms, String ipSecAlgoName) { if (IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName)) { algorithms.add(ipSecAlgoName); } } static { final List<String> algorithms = new ArrayList<>(); addAlgorithmIfSupported(algorithms, CRYPT_AES_CBC); addAlgorithmIfSupported(algorithms, CRYPT_AES_CTR); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA256); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA384); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA512); addAlgorithmIfSupported(algorithms, AUTH_AES_XCBC); addAlgorithmIfSupported(algorithms, AUTH_AES_CMAC); addAlgorithmIfSupported(algorithms, AUTH_CRYPT_AES_GCM); addAlgorithmIfSupported(algorithms, AUTH_CRYPT_CHACHA20_POLY1305); DEFAULT_ALGORITHMS = Collections.unmodifiableList(algorithms); } @NonNull private final String mServerAddr; @NonNull private final String mUserIdentity; Loading Loading @@ -195,8 +220,6 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * @param allowedAlgorithms The list to be validated */ private static void validateAllowedAlgorithms(@NonNull List<String> algorithmNames) { VpnProfile.validateAllowedAlgorithms(algorithmNames); // First, make sure no insecure algorithms were proposed. if (algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_MD5) || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA1)) { Loading core/java/com/android/internal/net/VpnProfile.java +24 −22 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.ProxyUtils; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -74,6 +77,9 @@ public final class VpnProfile implements Cloneable, Parcelable { private static final String ENCODED_NULL_PROXY_INFO = "\0\0\0\0"; /** Default URL encoding. */ private static final String DEFAULT_ENCODING = StandardCharsets.UTF_8.name(); // Entity fields. @UnsupportedAppUsage public final String key; // -1 Loading Loading @@ -129,9 +135,6 @@ public final class VpnProfile implements Cloneable, Parcelable { /** * The list of allowable algorithms. * * <p>This list is validated in the setter to ensure that encoding characters (list, value * delimiters) are not present in the algorithm names. See {@link #validateAllowedAlgorithms()} */ private List<String> mAllowedAlgorithms = new ArrayList<>(); // 19 public boolean isBypassable = false; // 20 Loading Loading @@ -196,11 +199,8 @@ public final class VpnProfile implements Cloneable, Parcelable { * * @param allowedAlgorithms the list of allowable algorithms, as listed in {@link * IpSecAlgorithm}. * @throws IllegalArgumentException if any delimiters are used in algorithm names. See {@link * #VALUE_DELIMITER} and {@link LIST_DELIMITER}. */ public void setAllowedAlgorithms(List<String> allowedAlgorithms) { validateAllowedAlgorithms(allowedAlgorithms); mAllowedAlgorithms = allowedAlgorithms; } Loading Loading @@ -297,7 +297,11 @@ public final class VpnProfile implements Cloneable, Parcelable { // Either all must be present, or none must be. if (values.length >= 24) { profile.mAllowedAlgorithms = Arrays.asList(values[19].split(LIST_DELIMITER)); profile.mAllowedAlgorithms = new ArrayList<>(); for (String algo : Arrays.asList(values[19].split(LIST_DELIMITER))) { profile.mAllowedAlgorithms.add(URLDecoder.decode(algo, DEFAULT_ENCODING)); } profile.isBypassable = Boolean.parseBoolean(values[20]); profile.isMetered = Boolean.parseBoolean(values[21]); profile.maxMtu = Integer.parseInt(values[22]); Loading Loading @@ -348,7 +352,19 @@ public final class VpnProfile implements Cloneable, Parcelable { builder.append(ENCODED_NULL_PROXY_INFO); } builder.append(VALUE_DELIMITER).append(String.join(LIST_DELIMITER, mAllowedAlgorithms)); final List<String> encodedAlgoNames = new ArrayList<>(); try { for (String algo : mAllowedAlgorithms) { encodedAlgoNames.add(URLEncoder.encode(algo, DEFAULT_ENCODING)); } } catch (UnsupportedEncodingException e) { // Unexpected error throw new IllegalStateException("Failed to encode algorithms.", e); } builder.append(VALUE_DELIMITER).append(String.join(LIST_DELIMITER, encodedAlgoNames)); builder.append(VALUE_DELIMITER).append(isBypassable); builder.append(VALUE_DELIMITER).append(isMetered); builder.append(VALUE_DELIMITER).append(maxMtu); Loading Loading @@ -425,20 +441,6 @@ public final class VpnProfile implements Cloneable, Parcelable { return true; } /** * Validates that the provided list of algorithms does not contain illegal characters. * * @param allowedAlgorithms The list to be validated */ public static void validateAllowedAlgorithms(List<String> allowedAlgorithms) { for (final String alg : allowedAlgorithms) { if (alg.contains(VALUE_DELIMITER) || alg.contains(LIST_DELIMITER)) { throw new IllegalArgumentException( "Algorithm contained illegal ('\0' or ',') character"); } } } /** Generates a hashcode over the VpnProfile. */ @Override public int hashCode() { Loading packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java +11 −3 Original line number Diff line number Diff line Loading @@ -29,8 +29,8 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.net.VpnProfile; import com.android.net.module.util.ProxyUtils; import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator; import com.android.net.module.util.ProxyUtils; import org.junit.Before; import org.junit.Test; Loading Loading @@ -170,7 +170,10 @@ public class Ikev2VpnProfileTest { final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); builder.setAuthPsk(PSK_BYTES); List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM); List<String> allowedAlgorithms = Arrays.asList( IpSecAlgorithm.AUTH_CRYPT_AES_GCM, IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305); builder.setAllowedAlgorithms(allowedAlgorithms); final Ikev2VpnProfile profile = builder.build(); Loading @@ -183,7 +186,12 @@ public class Ikev2VpnProfileTest { builder.setAuthPsk(PSK_BYTES); List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC); Arrays.asList( IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.AUTH_AES_XCBC, IpSecAlgorithm.AUTH_AES_CMAC, IpSecAlgorithm.CRYPT_AES_CBC, IpSecAlgorithm.CRYPT_AES_CTR); builder.setAllowedAlgorithms(allowedAlgorithms); final Ikev2VpnProfile profile = builder.build(); Loading packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java +1 −25 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.net.IpSecAlgorithm; Loading Loading @@ -97,6 +96,7 @@ public class VpnProfileTest { p.setAllowedAlgorithms( Arrays.asList( IpSecAlgorithm.AUTH_CRYPT_AES_GCM, IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC)); p.isBypassable = true; Loading Loading @@ -125,30 +125,6 @@ public class VpnProfileTest { assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23); } @Test public void testSetInvalidAlgorithmValueDelimiter() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); try { profile.setAllowedAlgorithms( Arrays.asList("test" + VpnProfile.VALUE_DELIMITER + "test")); fail("Expected failure due to value separator in algorithm name"); } catch (IllegalArgumentException expected) { } } @Test public void testSetInvalidAlgorithmListDelimiter() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); try { profile.setAllowedAlgorithms( Arrays.asList("test" + VpnProfile.LIST_DELIMITER + "test")); fail("Expected failure due to value separator in algorithm name"); } catch (IllegalArgumentException expected) { } } @Test public void testEncodeDecode() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); Loading services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +39 −16 Original line number Diff line number Diff line Loading @@ -213,19 +213,25 @@ public class VpnIkev2Utils { /** Builds a child SA proposal based on the allowed IPsec algorithms */ private static List<ChildSaProposal> getChildSaProposals(List<String> allowedAlgorithms) { // TODO: Add new IpSecAlgorithm in the followup commit final List<ChildSaProposal> proposals = new ArrayList<>(); final List<Integer> aesKeyLenOptions = Arrays.asList(KEY_LEN_AES_256, KEY_LEN_AES_192, KEY_LEN_AES_128); // Add non-AEAD options if (Ikev2VpnProfile.hasNormalModeAlgorithms(allowedAlgorithms)) { final ChildSaProposal.Builder normalModeBuilder = new ChildSaProposal.Builder(); // Encryption Algorithms: // AES-CBC is currently the only supported encryption algorithm. normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256); normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192); normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128); // AES-CBC and AES_CTR are currently the only supported encryption algorithms. for (int len : aesKeyLenOptions) { if (allowedAlgorithms.contains(IpSecAlgorithm.CRYPT_AES_CTR)) { normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CTR, len); } if (allowedAlgorithms.contains(IpSecAlgorithm.CRYPT_AES_CBC)) { normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, len); } } // Authentication/Integrity Algorithms: // Guaranteed by Ikev2VpnProfile constructor to contain at least one of these. Loading @@ -238,6 +244,12 @@ public class VpnIkev2Utils { if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_HMAC_SHA256)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_AES_XCBC)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_AES_XCBC_96); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_AES_CMAC)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_AES_CMAC_96); } ChildSaProposal proposal = normalModeBuilder.build(); if (proposal.getIntegrityAlgorithms().isEmpty()) { Loading @@ -252,16 +264,27 @@ public class VpnIkev2Utils { if (Ikev2VpnProfile.hasAeadAlgorithms(allowedAlgorithms)) { final ChildSaProposal.Builder aeadBuilder = new ChildSaProposal.Builder(); // AES-GCM is currently the only supported AEAD algorithm aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256); if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305)) { aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_CHACHA20_POLY1305, KEY_LEN_UNUSED); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_CRYPT_AES_GCM)) { aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128); } proposals.add(aeadBuilder.build()); } Loading Loading
core/java/android/net/Ikev2VpnProfile.java +32 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,16 @@ package android.net; 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; import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; import static com.android.internal.annotations.VisibleForTesting.Visibility; import static com.android.internal.util.Preconditions.checkStringNotEmpty; import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; Loading Loading @@ -70,13 +80,28 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private static final String EMPTY_CERT = ""; /** @hide */ public static final List<String> DEFAULT_ALGORITHMS = Collections.unmodifiableList(Arrays.asList( IpSecAlgorithm.CRYPT_AES_CBC, IpSecAlgorithm.AUTH_HMAC_SHA256, IpSecAlgorithm.AUTH_HMAC_SHA384, IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.AUTH_CRYPT_AES_GCM)); public static final List<String> DEFAULT_ALGORITHMS; private static void addAlgorithmIfSupported(List<String> algorithms, String ipSecAlgoName) { if (IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName)) { algorithms.add(ipSecAlgoName); } } static { final List<String> algorithms = new ArrayList<>(); addAlgorithmIfSupported(algorithms, CRYPT_AES_CBC); addAlgorithmIfSupported(algorithms, CRYPT_AES_CTR); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA256); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA384); addAlgorithmIfSupported(algorithms, AUTH_HMAC_SHA512); addAlgorithmIfSupported(algorithms, AUTH_AES_XCBC); addAlgorithmIfSupported(algorithms, AUTH_AES_CMAC); addAlgorithmIfSupported(algorithms, AUTH_CRYPT_AES_GCM); addAlgorithmIfSupported(algorithms, AUTH_CRYPT_CHACHA20_POLY1305); DEFAULT_ALGORITHMS = Collections.unmodifiableList(algorithms); } @NonNull private final String mServerAddr; @NonNull private final String mUserIdentity; Loading Loading @@ -195,8 +220,6 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * @param allowedAlgorithms The list to be validated */ private static void validateAllowedAlgorithms(@NonNull List<String> algorithmNames) { VpnProfile.validateAllowedAlgorithms(algorithmNames); // First, make sure no insecure algorithms were proposed. if (algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_MD5) || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA1)) { Loading
core/java/com/android/internal/net/VpnProfile.java +24 −22 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.ProxyUtils; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -74,6 +77,9 @@ public final class VpnProfile implements Cloneable, Parcelable { private static final String ENCODED_NULL_PROXY_INFO = "\0\0\0\0"; /** Default URL encoding. */ private static final String DEFAULT_ENCODING = StandardCharsets.UTF_8.name(); // Entity fields. @UnsupportedAppUsage public final String key; // -1 Loading Loading @@ -129,9 +135,6 @@ public final class VpnProfile implements Cloneable, Parcelable { /** * The list of allowable algorithms. * * <p>This list is validated in the setter to ensure that encoding characters (list, value * delimiters) are not present in the algorithm names. See {@link #validateAllowedAlgorithms()} */ private List<String> mAllowedAlgorithms = new ArrayList<>(); // 19 public boolean isBypassable = false; // 20 Loading Loading @@ -196,11 +199,8 @@ public final class VpnProfile implements Cloneable, Parcelable { * * @param allowedAlgorithms the list of allowable algorithms, as listed in {@link * IpSecAlgorithm}. * @throws IllegalArgumentException if any delimiters are used in algorithm names. See {@link * #VALUE_DELIMITER} and {@link LIST_DELIMITER}. */ public void setAllowedAlgorithms(List<String> allowedAlgorithms) { validateAllowedAlgorithms(allowedAlgorithms); mAllowedAlgorithms = allowedAlgorithms; } Loading Loading @@ -297,7 +297,11 @@ public final class VpnProfile implements Cloneable, Parcelable { // Either all must be present, or none must be. if (values.length >= 24) { profile.mAllowedAlgorithms = Arrays.asList(values[19].split(LIST_DELIMITER)); profile.mAllowedAlgorithms = new ArrayList<>(); for (String algo : Arrays.asList(values[19].split(LIST_DELIMITER))) { profile.mAllowedAlgorithms.add(URLDecoder.decode(algo, DEFAULT_ENCODING)); } profile.isBypassable = Boolean.parseBoolean(values[20]); profile.isMetered = Boolean.parseBoolean(values[21]); profile.maxMtu = Integer.parseInt(values[22]); Loading Loading @@ -348,7 +352,19 @@ public final class VpnProfile implements Cloneable, Parcelable { builder.append(ENCODED_NULL_PROXY_INFO); } builder.append(VALUE_DELIMITER).append(String.join(LIST_DELIMITER, mAllowedAlgorithms)); final List<String> encodedAlgoNames = new ArrayList<>(); try { for (String algo : mAllowedAlgorithms) { encodedAlgoNames.add(URLEncoder.encode(algo, DEFAULT_ENCODING)); } } catch (UnsupportedEncodingException e) { // Unexpected error throw new IllegalStateException("Failed to encode algorithms.", e); } builder.append(VALUE_DELIMITER).append(String.join(LIST_DELIMITER, encodedAlgoNames)); builder.append(VALUE_DELIMITER).append(isBypassable); builder.append(VALUE_DELIMITER).append(isMetered); builder.append(VALUE_DELIMITER).append(maxMtu); Loading Loading @@ -425,20 +441,6 @@ public final class VpnProfile implements Cloneable, Parcelable { return true; } /** * Validates that the provided list of algorithms does not contain illegal characters. * * @param allowedAlgorithms The list to be validated */ public static void validateAllowedAlgorithms(List<String> allowedAlgorithms) { for (final String alg : allowedAlgorithms) { if (alg.contains(VALUE_DELIMITER) || alg.contains(LIST_DELIMITER)) { throw new IllegalArgumentException( "Algorithm contained illegal ('\0' or ',') character"); } } } /** Generates a hashcode over the VpnProfile. */ @Override public int hashCode() { Loading
packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java +11 −3 Original line number Diff line number Diff line Loading @@ -29,8 +29,8 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.net.VpnProfile; import com.android.net.module.util.ProxyUtils; import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator; import com.android.net.module.util.ProxyUtils; import org.junit.Before; import org.junit.Test; Loading Loading @@ -170,7 +170,10 @@ public class Ikev2VpnProfileTest { final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); builder.setAuthPsk(PSK_BYTES); List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM); List<String> allowedAlgorithms = Arrays.asList( IpSecAlgorithm.AUTH_CRYPT_AES_GCM, IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305); builder.setAllowedAlgorithms(allowedAlgorithms); final Ikev2VpnProfile profile = builder.build(); Loading @@ -183,7 +186,12 @@ public class Ikev2VpnProfileTest { builder.setAuthPsk(PSK_BYTES); List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC); Arrays.asList( IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.AUTH_AES_XCBC, IpSecAlgorithm.AUTH_AES_CMAC, IpSecAlgorithm.CRYPT_AES_CBC, IpSecAlgorithm.CRYPT_AES_CTR); builder.setAllowedAlgorithms(allowedAlgorithms); final Ikev2VpnProfile profile = builder.build(); Loading
packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java +1 −25 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.net.IpSecAlgorithm; Loading Loading @@ -97,6 +96,7 @@ public class VpnProfileTest { p.setAllowedAlgorithms( Arrays.asList( IpSecAlgorithm.AUTH_CRYPT_AES_GCM, IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC)); p.isBypassable = true; Loading Loading @@ -125,30 +125,6 @@ public class VpnProfileTest { assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23); } @Test public void testSetInvalidAlgorithmValueDelimiter() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); try { profile.setAllowedAlgorithms( Arrays.asList("test" + VpnProfile.VALUE_DELIMITER + "test")); fail("Expected failure due to value separator in algorithm name"); } catch (IllegalArgumentException expected) { } } @Test public void testSetInvalidAlgorithmListDelimiter() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); try { profile.setAllowedAlgorithms( Arrays.asList("test" + VpnProfile.LIST_DELIMITER + "test")); fail("Expected failure due to value separator in algorithm name"); } catch (IllegalArgumentException expected) { } } @Test public void testEncodeDecode() { final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); Loading
services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +39 −16 Original line number Diff line number Diff line Loading @@ -213,19 +213,25 @@ public class VpnIkev2Utils { /** Builds a child SA proposal based on the allowed IPsec algorithms */ private static List<ChildSaProposal> getChildSaProposals(List<String> allowedAlgorithms) { // TODO: Add new IpSecAlgorithm in the followup commit final List<ChildSaProposal> proposals = new ArrayList<>(); final List<Integer> aesKeyLenOptions = Arrays.asList(KEY_LEN_AES_256, KEY_LEN_AES_192, KEY_LEN_AES_128); // Add non-AEAD options if (Ikev2VpnProfile.hasNormalModeAlgorithms(allowedAlgorithms)) { final ChildSaProposal.Builder normalModeBuilder = new ChildSaProposal.Builder(); // Encryption Algorithms: // AES-CBC is currently the only supported encryption algorithm. normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256); normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192); normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128); // AES-CBC and AES_CTR are currently the only supported encryption algorithms. for (int len : aesKeyLenOptions) { if (allowedAlgorithms.contains(IpSecAlgorithm.CRYPT_AES_CTR)) { normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CTR, len); } if (allowedAlgorithms.contains(IpSecAlgorithm.CRYPT_AES_CBC)) { normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, len); } } // Authentication/Integrity Algorithms: // Guaranteed by Ikev2VpnProfile constructor to contain at least one of these. Loading @@ -238,6 +244,12 @@ public class VpnIkev2Utils { if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_HMAC_SHA256)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_AES_XCBC)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_AES_XCBC_96); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_AES_CMAC)) { normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_AES_CMAC_96); } ChildSaProposal proposal = normalModeBuilder.build(); if (proposal.getIntegrityAlgorithms().isEmpty()) { Loading @@ -252,16 +264,27 @@ public class VpnIkev2Utils { if (Ikev2VpnProfile.hasAeadAlgorithms(allowedAlgorithms)) { final ChildSaProposal.Builder aeadBuilder = new ChildSaProposal.Builder(); // AES-GCM is currently the only supported AEAD algorithm aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256); if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305)) { aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_CHACHA20_POLY1305, KEY_LEN_UNUSED); } if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_CRYPT_AES_GCM)) { aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_192); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm( ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128); aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128); } proposals.add(aeadBuilder.build()); } Loading