summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtan Cohen <etancohen@google.com>2017-02-21 10:08:49 -0800
committerEtan Cohen <etancohen@google.com>2017-03-07 19:07:50 -0800
commit31389a22a6f12b12cca89d53b5f9f80fdcd76385 (patch)
tree3db6cf4f5871d2a6ae76441f6132d355f7cf8989
parent6f8030b6e550cffe6bea94a14c06173aeae0b873 (diff)
[AWARE] Add data-path security configuration (Passphrase)
Add support for Passphrase-based security. Bug: 33552694 Test: unit tests and integration (sl4a) tests Change-Id: Id883367f79ca38501e8670097a31245f048e5d71
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java26
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java21
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java35
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java12
4 files changed, 62 insertions, 32 deletions
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 851a580a2..5842a3bf8 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -315,14 +315,14 @@ public class WifiAwareDataPathStateManager {
if (DBG) {
Log.d(TAG, "onDataPathRequest: network request cache = " + mNetworkRequestsCache);
}
- mMgr.respondToDataPathRequest(false, ndpId, "", null);
+ mMgr.respondToDataPathRequest(false, ndpId, "", null, null);
return null;
}
if (nnri.state != AwareNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST) {
Log.w(TAG, "onDataPathRequest: request " + networkSpecifier + " is incorrect state="
+ nnri.state);
- mMgr.respondToDataPathRequest(false, ndpId, "", null);
+ mMgr.respondToDataPathRequest(false, ndpId, "", null, null);
mNetworkRequestsCache.remove(networkSpecifier);
return null;
}
@@ -330,7 +330,7 @@ public class WifiAwareDataPathStateManager {
nnri.state = AwareNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_RESPOND_RESPONSE;
nnri.ndpId = ndpId;
nnri.interfaceName = selectInterfaceForRequest(nnri);
- mMgr.respondToDataPathRequest(true, ndpId, nnri.interfaceName, nnri.pmk);
+ mMgr.respondToDataPathRequest(true, ndpId, nnri.interfaceName, nnri.pmk, nnri.passphrase);
return networkSpecifier;
}
@@ -631,7 +631,7 @@ public class WifiAwareDataPathStateManager {
nnri.interfaceName = selectInterfaceForRequest(nnri);
mMgr.initiateDataPathSetup(networkSpecifier, nnri.peerId,
NanDataPathChannelCfg.REQUEST_CHANNEL_SETUP, selectChannelForRequest(nnri),
- nnri.peerDiscoveryMac, nnri.interfaceName, nnri.pmk);
+ nnri.peerDiscoveryMac, nnri.interfaceName, nnri.pmk, nnri.passphrase);
nnri.state =
AwareNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE;
} else {
@@ -795,6 +795,7 @@ public class WifiAwareDataPathStateManager {
public int peerId = 0;
public byte[] peerDiscoveryMac = null;
public byte[] pmk = null;
+ public String passphrase = null;
public int ndpId;
public byte[] peerDataMac;
@@ -805,6 +806,7 @@ public class WifiAwareDataPathStateManager {
int type, role, uid, clientId, sessionId = 0, peerId = 0, pubSubId = 0;
byte[] peerMac = null;
byte[] pmk = null;
+ String passphrase = null;
if (VDBG) {
Log.v(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier);
@@ -879,6 +881,21 @@ public class WifiAwareDataPathStateManager {
if (pmk != null && pmk.length == 0) {
pmk = null;
}
+
+ // passphrase: always present (though can be an empty string - equivalent to null)
+ passphrase = jsonObject.getString(
+ WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE);
+ if (passphrase != null && passphrase.length() == 0) {
+ passphrase = null;
+ }
+
+ if (passphrase != null) {
+ if (pmk != null) {
+ Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+ + " -- invalid: can't specify both PMK and Passphrase");
+ return null;
+ }
+ }
} catch (JSONException e) {
Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+ " -- invalid JSON format -- e=" + e);
@@ -950,6 +967,7 @@ public class WifiAwareDataPathStateManager {
nnri.peerId = peerId;
nnri.peerDiscoveryMac = peerMac;
nnri.pmk = pmk;
+ nnri.passphrase = passphrase;
return nnri;
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
index a3953cd6f..7990db7d1 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
@@ -584,7 +584,8 @@ public class WifiAwareNativeApi {
}
/**
- * Initiates setting up a data-path between device and peer.
+ * Initiates setting up a data-path between device and peer. Security is provided by either
+ * PMK or Passphrase - if both are null then an open (unencrypted) link is set up.
*
* @param transactionId Transaction ID for the transaction - used in the async callback to
* match with the original request.
@@ -596,12 +597,13 @@ public class WifiAwareNativeApi {
* @param channel The channel on which to set up the data-path.
* @param peer The MAC address of the peer to create a connection with.
* @param interfaceName The interface on which to create the data connection.
- * @param pmk Pairwise master key (PMK, see IEEE 802.11i). Null value means an unsecured (open)
- * datapath.
+ * @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
+ * @param passphrase Passphrase for the data-path.
* @param capabilities The capabilities of the firmware.
*/
public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
- int channel, byte[] peer, String interfaceName, byte[] pmk, Capabilities capabilities) {
+ int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase,
+ Capabilities capabilities) {
if (VDBG) {
Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId
+ ", channelRequestType=" + channelRequestType + ", channel=" + channel
@@ -633,6 +635,7 @@ public class WifiAwareNativeApi {
req.cipherType = getStrongestCipherSuiteType(capabilities.supportedCipherSuites);
convertLcByteToUcByteArray(pmk, req.pmk);
}
+ // TODO: b/35866810 connect passphrase to HAL!
try {
WifiStatus status = iface.initiateDataPathRequest(transactionId, req);
@@ -649,7 +652,8 @@ public class WifiAwareNativeApi {
}
/**
- * Responds to a data request from a peer.
+ * Responds to a data request from a peer. Security is provided by either PMK or Passphrase -
+ * if both are null then an open (unencrypted) link is set up.
*
* @param transactionId Transaction ID for the transaction - used in the async callback to
* match with the original request.
@@ -657,12 +661,12 @@ public class WifiAwareNativeApi {
* @param ndpId The NDP (Aware data path) ID. Obtained from the request callback.
* @param interfaceName The interface on which the data path will be setup. Obtained from the
* request callback.
- * @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path. A null indicates
- * an unsecure (open) link.
+ * @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
+ * @param passphrase Passphrase for the data-path.
* @param capabilities The capabilities of the firmware.
*/
public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
- String interfaceName, byte[] pmk, Capabilities capabilities) {
+ String interfaceName, byte[] pmk, String passphrase, Capabilities capabilities) {
if (VDBG) {
Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept="
+ accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName);
@@ -690,6 +694,7 @@ public class WifiAwareNativeApi {
req.cipherType = getStrongestCipherSuiteType(capabilities.supportedCipherSuites);
convertLcByteToUcByteArray(pmk, req.pmk);
}
+ // TODO: b/35866810 connect passphrase to HAL!
try {
WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 542b66455..76bfcea55 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -169,6 +169,7 @@ public class WifiAwareStateManager {
private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ = "message_arrival_seq";
private static final String MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE = "notify_identity_chg";
private static final String MESSAGE_BUNDLE_KEY_PMK = "pmk";
+ private static final String MESSAGE_BUNDLE_KEY_PASSPHRASE = "passphrase";
private WifiAwareNativeApi mWifiAwareNativeApi;
@@ -465,7 +466,7 @@ public class WifiAwareStateManager {
* Command to initiate a data-path (executed by the initiator).
*/
public void initiateDataPathSetup(String networkSpecifier, int peerId, int channelRequestType,
- int channel, byte[] peer, String interfaceName, byte[] pmk) {
+ int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_INITIATE_DATA_PATH_SETUP;
msg.obj = networkSpecifier;
@@ -475,6 +476,7 @@ public class WifiAwareStateManager {
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peer);
msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PMK, pmk);
+ msg.getData().putString(MESSAGE_BUNDLE_KEY_PASSPHRASE, passphrase);
mSm.sendMessage(msg);
}
@@ -482,13 +484,14 @@ public class WifiAwareStateManager {
* Command to respond to the data-path request (executed by the responder).
*/
public void respondToDataPathRequest(boolean accept, int ndpId, String interfaceName,
- byte[] pmk) {
+ byte[] pmk, String passphrase) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST;
msg.arg2 = ndpId;
msg.obj = accept;
msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PMK, pmk);
+ msg.getData().putString(MESSAGE_BUNDLE_KEY_PASSPHRASE, passphrase);
mSm.sendMessage(msg);
}
@@ -634,7 +637,7 @@ public class WifiAwareStateManager {
/**
* Response from firmware to {@link #initiateDataPathSetup(String, int, int, int, byte[],
- * String, byte[])}. Indicates that command has started succesfully (not completed!).
+ * String, byte[], String)}. Indicates that command has started succesfully (not completed!).
*/
public void onInitiateDataPathResponseSuccess(short transactionId, int ndpId) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
@@ -646,8 +649,8 @@ public class WifiAwareStateManager {
/**
* Response from firmware to
- * {@link #initiateDataPathSetup(String, int, int, int, byte[], String, byte[])}. Indicates
- * that command has failed.
+ * {@link #initiateDataPathSetup(String, int, int, int, byte[], String, byte[], String)}.
+ * Indicates that command has failed.
*/
public void onInitiateDataPathResponseFail(short transactionId, int reason) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
@@ -658,7 +661,8 @@ public class WifiAwareStateManager {
}
/**
- * Response from firmware to {@link #respondToDataPathRequest(boolean, int, String, byte[])}.
+ * Response from firmware to
+ * {@link #respondToDataPathRequest(boolean, int, String, byte[], String)}.
*/
public void onRespondToDataPathSetupRequestResponse(short transactionId, boolean success,
int reasonOnFailure) {
@@ -1368,10 +1372,11 @@ public class WifiAwareStateManager {
byte[] peer = data.getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS);
String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME);
byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PMK);
+ String passphrase = data.getString(MESSAGE_BUNDLE_KEY_PASSPHRASE);
waitForResponse = initiateDataPathSetupLocal(mCurrentTransactionId,
networkSpecifier, peerId, channelRequestType, channel, peer,
- interfaceName, pmk);
+ interfaceName, pmk, passphrase);
if (waitForResponse) {
WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
@@ -1390,9 +1395,10 @@ public class WifiAwareStateManager {
boolean accept = (boolean) msg.obj;
String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME);
byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PMK);
+ String passphrase = data.getString(MESSAGE_BUNDLE_KEY_PASSPHRASE);
waitForResponse = respondToDataPathRequestLocal(mCurrentTransactionId, accept,
- ndpId, interfaceName, pmk);
+ ndpId, interfaceName, pmk, passphrase);
break;
}
@@ -2064,18 +2070,19 @@ public class WifiAwareStateManager {
private boolean initiateDataPathSetupLocal(short transactionId, String networkSpecifier,
int peerId, int channelRequestType, int channel, byte[] peer, String interfaceName,
- byte[] pmk) {
+ byte[] pmk, String passphrase) {
if (VDBG) {
Log.v(TAG,
"initiateDataPathSetupLocal(): transactionId=" + transactionId
+ ", networkSpecifier=" + networkSpecifier + ", peerId=" + peerId
+ ", channelRequestType=" + channelRequestType + ", channel=" + channel
+ ", peer=" + String.valueOf(HexEncoding.encode(peer))
- + ", interfaceName=" + interfaceName + ", pmk=" + pmk);
+ + ", interfaceName=" + interfaceName + ", pmk=" + pmk
+ + ", passphrase=" + passphrase);
}
boolean success = mWifiAwareNativeApi.initiateDataPath(transactionId, peerId,
- channelRequestType, channel, peer, interfaceName, pmk, mCapabilities);
+ channelRequestType, channel, peer, interfaceName, pmk, passphrase, mCapabilities);
if (!success) {
mDataPathMgr.onDataPathInitiateFail(networkSpecifier, NanStatusType.INTERNAL_FAILURE);
}
@@ -2084,16 +2091,16 @@ public class WifiAwareStateManager {
}
private boolean respondToDataPathRequestLocal(short transactionId, boolean accept,
- int ndpId, String interfaceName, byte[] pmk) {
+ int ndpId, String interfaceName, byte[] pmk, String passphrase) {
if (VDBG) {
Log.v(TAG,
"respondToDataPathRequestLocal(): transactionId=" + transactionId + ", accept="
+ accept + ", ndpId=" + ndpId + ", interfaceName=" + interfaceName
- + ", pmk=" + pmk);
+ + ", pmk=" + pmk + ", passphrase=" + passphrase);
}
boolean success = mWifiAwareNativeApi.respondToDataPathRequest(transactionId, accept, ndpId,
- interfaceName, pmk, mCapabilities);
+ interfaceName, pmk, passphrase, mCapabilities);
if (!success) {
mDataPathMgr.onRespondToDataPathRequest(ndpId, false);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
index 6a13576e6..724a4b053 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -139,10 +139,10 @@ public class WifiAwareDataPathStateManagerTest {
when(mMockNative.createAwareNetworkInterface(anyShort(), anyString())).thenReturn(true);
when(mMockNative.deleteAwareNetworkInterface(anyShort(), anyString())).thenReturn(true);
when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
- any(byte[].class), anyString(), any(byte[].class),
+ any(byte[].class), anyString(), any(byte[].class), anyString(),
any(Capabilities.class))).thenReturn(true);
when(mMockNative.respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(), anyString(),
- any(byte[].class), any(Capabilities.class))).thenReturn(true);
+ any(byte[].class), anyString(), any(Capabilities.class))).thenReturn(true);
when(mMockNative.endDataPath(anyShort(), anyInt())).thenReturn(true);
when(mMockNetworkInterface.configureAgentProperties(
@@ -444,7 +444,7 @@ public class WifiAwareDataPathStateManagerTest {
mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
- eq(ndpId), eq(""), eq(null), any(Capabilities.class));
+ eq(ndpId), eq(""), eq(null), eq(null), any(Capabilities.class));
}
verifyNoMoreInteractions(mMockNative, mMockCm);
@@ -468,7 +468,7 @@ public class WifiAwareDataPathStateManagerTest {
if (immediateHalFailure) {
when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
- any(byte[].class), anyString(), any(byte[].class),
+ any(byte[].class), anyString(), any(byte[].class), anyString(),
any(Capabilities.class))).thenReturn(false);
}
@@ -497,7 +497,7 @@ public class WifiAwareDataPathStateManagerTest {
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
eq(useDirect ? 0 : peerHandle.peerId),
eq(REQUEST_CHANNEL_SETUP), eq(2437), eq(peerDiscoveryMac),
- eq(sAwareInterfacePrefix + "0"), eq(pmk), any(Capabilities.class));
+ eq(sAwareInterfacePrefix + "0"), eq(pmk), eq(null), any(Capabilities.class));
if (immediateHalFailure) {
// short-circuit the rest of this test
verifyNoMoreInteractions(mMockNative, mMockCm);
@@ -586,7 +586,7 @@ public class WifiAwareDataPathStateManagerTest {
mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true),
- eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
+ eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null), eq(null),
any(Capabilities.class));
mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();