From 2ed005834f7e8d2d9cb55d4c1db24504857e26d6 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Thu, 9 Apr 2020 21:49:05 -0700 Subject: Add filtering for IPsec algorithms in IKEv2 VPNs This commit adds support for validating and filtering IPsec algorithms. Without a public API exposing IKEv2 algorithms (and their respective public APIs), the allowedAlgorithms can only filter the proposals for IPsec (Child) SA algorithms. Additionally, this removes the HMAC_SHA1 from the IKE SA's integrity algorithm proposals due to insecurity Bug: 153701879 Test: FrameworksNetTests passing, new tests added Change-Id: I7e61a1612692db275b751330af5bacbf86836a8c --- core/java/android/net/Ikev2VpnProfile.java | 78 ++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-) (limited to 'core/java') diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 81d03f07d0be..afa63039b6f7 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -70,6 +70,15 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private static final String MISSING_PARAM_MSG_TMPL = "Required parameter was not provided: %s"; private static final String EMPTY_CERT = ""; + /** @hide */ + public static final List 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)); + @NonNull private final String mServerAddr; @NonNull private final String mUserIdentity; @@ -172,7 +181,56 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { throw new IllegalArgumentException("Invalid auth method set"); } - VpnProfile.validateAllowedAlgorithms(mAllowedAlgorithms); + validateAllowedAlgorithms(mAllowedAlgorithms); + } + + /** + * Validates that the allowed algorithms are a valid set for IPsec purposes + * + *

In order for the algorithm list to be a valid set, it must contain at least one algorithm + * that provides Authentication, and one that provides Encryption. Authenticated Encryption with + * Associated Data (AEAD) algorithms are counted as providing Authentication and Encryption. + * + * @param allowedAlgorithms The list to be validated + */ + private static void validateAllowedAlgorithms(@NonNull List 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)) { + throw new IllegalArgumentException("Algorithm not supported for IKEv2 VPN profiles"); + } + + // Validate that some valid combination (AEAD or AUTH + CRYPT) is present + if (hasAeadAlgorithms(algorithmNames) || hasNormalModeAlgorithms(algorithmNames)) { + return; + } + + throw new IllegalArgumentException("Algorithm set missing support for Auth, Crypt or both"); + } + + /** + * Checks if the provided list has AEAD algorithms + * + * @hide + */ + public static boolean hasAeadAlgorithms(@NonNull List algorithmNames) { + return algorithmNames.contains(IpSecAlgorithm.AUTH_CRYPT_AES_GCM); + } + + /** + * Checks the provided list has acceptable (non-AEAD) authentication and encryption algorithms + * + * @hide + */ + public static boolean hasNormalModeAlgorithms(@NonNull List algorithmNames) { + final boolean hasCrypt = algorithmNames.contains(IpSecAlgorithm.CRYPT_AES_CBC); + final boolean hasAuth = algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA256) + || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA384) + || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA512); + + return hasCrypt && hasAuth; } /** Retrieves the server address string. */ @@ -559,7 +617,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @Nullable private X509Certificate mUserCert; @Nullable private ProxyInfo mProxyInfo; - @NonNull private List mAllowedAlgorithms = new ArrayList<>(); + @NonNull private List mAllowedAlgorithms = DEFAULT_ALGORITHMS; private boolean mIsBypassable = false; private boolean mIsMetered = true; private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT; @@ -756,7 +814,19 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { /** * Sets the allowable set of IPsec algorithms * - *

A list of allowed IPsec algorithms as defined in {@link IpSecAlgorithm} + *

If set, this will constrain the set of algorithms that the IPsec tunnel will use for + * integrity verification and encryption to the provided list. + * + *

The set of allowed IPsec algorithms is defined in {@link IpSecAlgorithm}. Adding of + * algorithms that are considered insecure (such as AUTH_HMAC_MD5 and AUTH_HMAC_SHA1) is not + * permitted, and will result in an IllegalArgumentException being thrown. + * + *

The provided algorithm list must contain at least one algorithm that provides + * Authentication, and one that provides Encryption. Authenticated Encryption with + * Associated Data (AEAD) algorithms provide both Authentication and Encryption. + * + *

By default, this profile will use any algorithm defined in {@link IpSecAlgorithm}, + * with the exception of those considered insecure (as described above). * * @param algorithmNames the list of supported IPsec algorithms * @return this {@link Builder} object to facilitate chaining of method calls @@ -765,7 +835,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @NonNull public Builder setAllowedAlgorithms(@NonNull List algorithmNames) { checkNotNull(algorithmNames, MISSING_PARAM_MSG_TMPL, "algorithmNames"); - VpnProfile.validateAllowedAlgorithms(algorithmNames); + validateAllowedAlgorithms(algorithmNames); mAllowedAlgorithms = algorithmNames; return this; -- cgit v1.2.3