Merge "[AWARE] Add validity check on PMK/Passphrase lengths" into oc-dr1-dev

This commit is contained in:
Etan Cohen
2017-06-08 05:26:13 +00:00
committed by Android (Google) Code Review
5 changed files with 204 additions and 10 deletions

View File

@@ -609,6 +609,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android.hardware.usb-V1.1-java-constants \ android.hardware.usb-V1.1-java-constants \
android.hardware.vibrator-V1.0-java-constants \ android.hardware.vibrator-V1.0-java-constants \
android.hardware.vibrator-V1.1-java-constants \ android.hardware.vibrator-V1.1-java-constants \
android.hardware.wifi-V1.0-java-constants \
# Loaded with System.loadLibrary by android.view.textclassifier # Loaded with System.loadLibrary by android.view.textclassifier
LOCAL_REQUIRED_MODULES += libtextclassifier LOCAL_REQUIRED_MODULES += libtextclassifier

View File

@@ -342,8 +342,8 @@ public class DiscoverySession implements AutoCloseable {
*/ */
public NetworkSpecifier createNetworkSpecifierPassphrase( public NetworkSpecifier createNetworkSpecifierPassphrase(
@Nullable PeerHandle peerHandle, @NonNull String passphrase) { @Nullable PeerHandle peerHandle, @NonNull String passphrase) {
if (passphrase == null || passphrase.length() == 0) { if (!WifiAwareUtils.validatePassphrase(passphrase)) {
throw new IllegalArgumentException("Passphrase must not be null or empty"); throw new IllegalArgumentException("Passphrase must meet length requirements");
} }
if (mTerminated) { if (mTerminated) {
@@ -405,8 +405,8 @@ public class DiscoverySession implements AutoCloseable {
@SystemApi @SystemApi
public NetworkSpecifier createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle, public NetworkSpecifier createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
@NonNull byte[] pmk) { @NonNull byte[] pmk) {
if (pmk == null || pmk.length == 0) { if (!WifiAwareUtils.validatePmk(pmk)) {
throw new IllegalArgumentException("PMK must not be null or empty"); throw new IllegalArgumentException("PMK must 32 bytes");
} }
if (mTerminated) { if (mTerminated) {

View File

@@ -269,9 +269,10 @@ public class WifiAwareSession implements AutoCloseable {
Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination"); Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
return null; return null;
} }
if (passphrase == null || passphrase.length() == 0) { if (!WifiAwareUtils.validatePassphrase(passphrase)) {
throw new IllegalArgumentException("Passphrase must not be null or empty"); throw new IllegalArgumentException("Passphrase must meet length requirements");
} }
return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase); return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
} }
@@ -319,8 +320,8 @@ public class WifiAwareSession implements AutoCloseable {
Log.e(TAG, "createNetworkSpecifierPmk: called after termination"); Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
return null; return null;
} }
if (pmk == null || pmk.length == 0) { if (!WifiAwareUtils.validatePmk(pmk)) {
throw new IllegalArgumentException("PMK must not be null or empty"); throw new IllegalArgumentException("PMK must 32 bytes");
} }
return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null); return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
} }

View File

@@ -16,6 +16,8 @@
package android.net.wifi.aware; package android.net.wifi.aware;
import android.hardware.wifi.V1_0.Constants;
/** /**
* Provides utilities for the Wifi Aware manager/service. * Provides utilities for the Wifi Aware manager/service.
* *
@@ -51,4 +53,35 @@ public class WifiAwareUtils {
++index; ++index;
} }
} }
/**
* Validates that the passphrase is a non-null string of the right size (per the HAL min/max
* length parameters).
*
* @param passphrase Passphrase to test
* @return true if passphrase is valid, false if not
*/
public static boolean validatePassphrase(String passphrase) {
if (passphrase == null
|| passphrase.length() < Constants.NanParamSizeLimits.MIN_PASSPHRASE_LENGTH
|| passphrase.length() > Constants.NanParamSizeLimits.MAX_PASSPHRASE_LENGTH) {
return false;
}
return true;
}
/**
* Validates that the PMK is a non-null byte array of the right size (32 bytes per spec).
*
* @param pmk PMK to test
* @return true if PMK is valid, false if not
*/
public static boolean validatePmk(byte[] pmk) {
if (pmk == null || pmk.length != 32) {
return false;
}
return true;
}
} }

View File

@@ -32,6 +32,7 @@ import android.net.wifi.RttManager;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.RemoteException;
import android.os.test.TestLooper; import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
@@ -938,7 +939,7 @@ public class WifiAwareManagerTest {
final int sessionId = 123; final int sessionId = 123;
final PeerHandle peerHandle = new PeerHandle(123412); final PeerHandle peerHandle = new PeerHandle(123412);
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER; final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
final byte[] pmk = "Some arbitrary byte array".getBytes(); final byte[] pmk = "01234567890123456789012345678901".getBytes();
final String passphrase = "A really bad password"; final String passphrase = "A really bad password";
final ConfigRequest configRequest = new ConfigRequest.Builder().build(); final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final PublishConfig publishConfig = new PublishConfig.Builder().build(); final PublishConfig publishConfig = new PublishConfig.Builder().build();
@@ -1019,7 +1020,7 @@ public class WifiAwareManagerTest {
final ConfigRequest configRequest = new ConfigRequest.Builder().build(); final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false); final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR; final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
final byte[] pmk = "Some arbitrary pmk data".getBytes(); final byte[] pmk = "01234567890123456789012345678901".getBytes();
final String passphrase = "A really bad password"; final String passphrase = "A really bad password";
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass( ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
@@ -1070,4 +1071,162 @@ public class WifiAwareManagerTest {
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService, verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession, mockRttListener); mockPublishSession, mockRttListener);
} }
/**
* Validate that a null PMK triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierWithClientNullPmk() throws Exception {
executeNetworkSpecifierWithClient(true, null, null);
}
/**
* Validate that a non-32-bytes PMK triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
executeNetworkSpecifierWithClient(true, "012".getBytes(), null);
}
/**
* Validate that a null Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierWithClientNullPassphrase() throws Exception {
executeNetworkSpecifierWithClient(false, null, null);
}
/**
* Validate that a too short Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierWithClientShortPassphrase() throws Exception {
executeNetworkSpecifierWithClient(false, null, "012");
}
/**
* Validate that a too long Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierWithClientLongPassphrase() throws Exception {
executeNetworkSpecifierWithClient(false, null,
"0123456789012345678901234567890123456789012345678901234567890123456789");
}
private void executeNetworkSpecifierWithClient(boolean doPmk, byte[] pmk, String passphrase)
throws Exception {
final int clientId = 4565;
final int sessionId = 123;
final PeerHandle peerHandle = new PeerHandle(123412);
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final PublishConfig publishConfig = new PublishConfig.Builder().build();
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
WifiAwareSession.class);
ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
.forClass(PublishDiscoverySession.class);
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession, mockRttListener);
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
WifiAwareSession session = sessionCaptor.getValue();
// (2) publish successfully
session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
sessionProxyCallback.capture());
sessionProxyCallback.getValue().onSessionStarted(sessionId);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
// (3) create network specifier
if (doPmk) {
publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
} else {
publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle, passphrase);
}
}
/**
* Validate that a null PMK triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierDirectNullPmk() throws Exception {
executeNetworkSpecifierDirect(true, null, null);
}
/**
* Validate that a non-32-bytes PMK triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
executeNetworkSpecifierDirect(true, "012".getBytes(), null);
}
/**
* Validate that a null Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
executeNetworkSpecifierDirect(false, null, null);
}
/**
* Validate that a too short Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierDirectShortPassphrase() throws Exception {
executeNetworkSpecifierDirect(false, null, "012");
}
/**
* Validate that a too long Passphrase triggers an exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testNetworkSpecifierDirectLongPassphrase() throws Exception {
executeNetworkSpecifierDirect(false, null,
"0123456789012345678901234567890123456789012345678901234567890123456789");
}
private void executeNetworkSpecifierDirect(boolean doPmk, byte[] pmk, String passphrase)
throws Exception {
final int clientId = 134;
final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
WifiAwareSession.class);
ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
.forClass(IWifiAwareEventCallback.class);
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession, mockRttListener);
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
// (2) create network specifier
if (doPmk) {
sessionCaptor.getValue().createNetworkSpecifierPmk(role, someMac, pmk);
} else {
sessionCaptor.getValue().createNetworkSpecifierPassphrase(role, someMac, passphrase);
}
}
} }