From c7b445ba6b5b5916d47daf22a77e6f67de3fc5f4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 27 Apr 2018 10:28:27 -0700 Subject: WifiConfigurationUtil: Validate UTF-8 ssid length correctly Validate the number of bytes in UTF-8 encoded SSID's. The previous check was only validating the number of characters which could end up violating the SSID length specification in the standard. Also, added an extra validation in NativeUtil.decodeSsid() to ensure the string is UTF-8 encoded. Bug: 78483295 Test: Unit tests Test: Able to add/update wifi network configs. Change-Id: I46076ba6b309af006c10f6a9d4ab1d9bc40be428 --- .../android/server/wifi/WifiConfigurationUtil.java | 27 +++++++++++++--------- .../com/android/server/wifi/util/NativeUtil.java | 16 +++++++++---- 2 files changed, 27 insertions(+), 16 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java index f8b2f3d0a..8d94862e2 100644 --- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java +++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java @@ -29,6 +29,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.util.NativeUtil; +import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.BitSet; @@ -49,8 +50,8 @@ public class WifiConfigurationUtil { * Constants used for validating external config objects. */ private static final int ENCLOSING_QUTOES_LEN = 2; - private static final int SSID_ASCII_MIN_LEN = 1 + ENCLOSING_QUTOES_LEN; - private static final int SSID_ASCII_MAX_LEN = 32 + ENCLOSING_QUTOES_LEN; + private static final int SSID_UTF_8_MIN_LEN = 1 + ENCLOSING_QUTOES_LEN; + private static final int SSID_UTF_8_MAX_LEN = 32 + ENCLOSING_QUTOES_LEN; private static final int SSID_HEX_MIN_LEN = 2; private static final int SSID_HEX_MAX_LEN = 64; private static final int PSK_ASCII_MIN_LEN = 8 + ENCLOSING_QUTOES_LEN; @@ -282,13 +283,16 @@ public class WifiConfigurationUtil { return false; } if (ssid.startsWith("\"")) { - // ASCII SSID string - if (ssid.length() < SSID_ASCII_MIN_LEN) { - Log.e(TAG, "validateSsid failed: ascii string size too small: " + ssid.length()); + // UTF-8 SSID string + byte[] ssidBytes = ssid.getBytes(StandardCharsets.UTF_8); + if (ssidBytes.length < SSID_UTF_8_MIN_LEN) { + Log.e(TAG, "validateSsid failed: utf-8 ssid string size too small: " + + ssidBytes.length); return false; } - if (ssid.length() > SSID_ASCII_MAX_LEN) { - Log.e(TAG, "validateSsid failed: ascii string size too large: " + ssid.length()); + if (ssidBytes.length > SSID_UTF_8_MAX_LEN) { + Log.e(TAG, "validateSsid failed: utf-8 ssid string size too large: " + + ssidBytes.length); return false; } } else { @@ -333,12 +337,13 @@ public class WifiConfigurationUtil { } if (psk.startsWith("\"")) { // ASCII PSK string - if (psk.length() < PSK_ASCII_MIN_LEN) { - Log.e(TAG, "validatePsk failed: ascii string size too small: " + psk.length()); + byte[] pskBytes = psk.getBytes(StandardCharsets.US_ASCII); + if (pskBytes.length < PSK_ASCII_MIN_LEN) { + Log.e(TAG, "validatePsk failed: ascii string size too small: " + pskBytes.length); return false; } - if (psk.length() > PSK_ASCII_MAX_LEN) { - Log.e(TAG, "validatePsk failed: ascii string size too large: " + psk.length()); + if (pskBytes.length > PSK_ASCII_MAX_LEN) { + Log.e(TAG, "validatePsk failed: ascii string size too large: " + pskBytes.length); return false; } } else { diff --git a/service/java/com/android/server/wifi/util/NativeUtil.java b/service/java/com/android/server/wifi/util/NativeUtil.java index 84f93514c..4083cefdf 100644 --- a/service/java/com/android/server/wifi/util/NativeUtil.java +++ b/service/java/com/android/server/wifi/util/NativeUtil.java @@ -28,6 +28,7 @@ import java.nio.ByteOrder; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -46,17 +47,22 @@ public class NativeUtil { * Convert the string to byte array list. * * @return the UTF_8 char byte values of str, as an ArrayList. - * @throws IllegalArgumentException if a null string is sent. + * @throws IllegalArgumentException if a null or unencodable string is sent. */ public static ArrayList stringToByteArrayList(String str) { if (str == null) { throw new IllegalArgumentException("null string"); } - ArrayList byteArrayList = new ArrayList(); - for (byte b : str.getBytes(StandardCharsets.UTF_8)) { - byteArrayList.add(new Byte(b)); + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); } - return byteArrayList; } /** -- cgit v1.2.3