Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 769fa0c8 authored by Etan Cohen's avatar Etan Cohen Committed by Gerrit Code Review
Browse files

Merge "[AWARE] Add data-path security configuration (Passphrase)"

parents 0a11c830 62a2f9f6
Loading
Loading
Loading
Loading
+106 −39
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ public class DiscoverySession {
            Log.w(TAG, "terminate: already terminated.");
            return;
        }

        mTerminated = true;
        mMgr.clear();
        mCloseGuard.close();
@@ -172,7 +173,8 @@ public class DiscoverySession {
        if (mTerminated) {
            Log.w(TAG, "sendMessage: called on terminated session");
            return;
        } else {
        }

        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.w(TAG, "sendMessage: called post GC on WifiAwareManager");
@@ -181,7 +183,6 @@ public class DiscoverySession {

        mgr.sendMessage(mClientId, mSessionId, peerHandle, message, messageId, retryCount);
    }
    }

    /**
     * Sends a message to the specified destination. Aware messages are transmitted in the context
@@ -235,7 +236,8 @@ public class DiscoverySession {
        if (mTerminated) {
            Log.w(TAG, "startRanging: called on terminated session");
            return;
        } else {
        }

        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.w(TAG, "startRanging: called post GC on WifiAwareManager");
@@ -244,7 +246,6 @@ public class DiscoverySession {

        mgr.startRanging(mClientId, mSessionId, params, listener);
    }
    }

    /**
     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
@@ -261,6 +262,9 @@ public class DiscoverySession {
     * <p>
     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
     * and a Publisher is a RESPONDER.
     * <p>
     * To set up an encrypted link use the {@link #createNetworkSpecifierPmk(PeerHandle, byte[])}
     * or {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} APIs.
     *
     * @param peerHandle The peer's handle obtained through
     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
@@ -282,7 +286,8 @@ public class DiscoverySession {
        if (mTerminated) {
            Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
            return null;
        } else {
        }

        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
@@ -293,8 +298,69 @@ public class DiscoverySession {
                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;

            return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null);
        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null, null);
    }

    /**
     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
     * encrypted WiFi Aware connection (link) to the specified peer. The
     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
     * <p>
     * This method should be used when setting up a connection with a peer discovered through Aware
     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
     * OOB (out-of-band) mechanism then use the alternative
     * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)} method -
     * which uses the peer's MAC address.
     * <p>
     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
     * and a Publisher is a RESPONDER.
     *
     * @param peerHandle The peer's handle obtained through
     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
     * byte[], java.util.List)} or
     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
     *                   from only that peer. A RESPONDER may specify a null - indicating that
     *                   it will accept connection requests from any device.
     * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
     *                   the passphrase. Use the
     *                   {@link #createNetworkSpecifierPmk(PeerHandle, byte[])} to specify the
     *                   PMK directly or {@link #createNetworkSpecifierOpen(PeerHandle)} to
     *                   specify an open (unencrypted) link.
     *
     * @return A string to be used to construct
     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
     * android.net.ConnectivityManager.NetworkCallback)}
     * [or other varieties of that API].
     *
     * * @hide
     */
    public String createNetworkSpecifierPassphrase(@Nullable PeerHandle peerHandle,
            @NonNull String passphrase) {
        if (passphrase == null || passphrase.length() == 0) {
            throw new IllegalArgumentException("Passphrase must not be null or empty");
        }

        if (mTerminated) {
            Log.w(TAG, "createNetworkSpecifierPassphrase: called on terminated session");
            return null;
        }

        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.w(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
            return null;
        }

        int role = this instanceof SubscribeDiscoverySession
                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;

        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null,
                passphrase);
    }

    /**
@@ -307,8 +373,8 @@ public class DiscoverySession {
     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
     * OOB (out-of-band) mechanism then use the alternative
     * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses the
     * peer's MAC address.
     * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses
     * the peer's MAC address.
     * <p>
     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
     * and a Publisher is a RESPONDER.
@@ -322,8 +388,9 @@ public class DiscoverySession {
     *                   it will accept connection requests from any device.
     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
     *            encrypting the data-path. Use the
     *            {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an open (unencrypted)
     *            link.
     *            {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} to specify a
     *            Passphrase or {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an
     *            open (unencrypted) link.
     *
     * @return A string to be used to construct
     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
@@ -342,7 +409,8 @@ public class DiscoverySession {
        if (mTerminated) {
            Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session");
            return null;
        } else {
        }

        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
@@ -353,8 +421,7 @@ public class DiscoverySession {
                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;

            return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk);
        }
        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk, null);
    }

    /**
+22 −8
Original line number Diff line number Diff line
@@ -130,26 +130,26 @@ public class WifiAwareManager {
     */

    /**
     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk optional
     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional
     * @hide
     */
    public static final int NETWORK_SPECIFIER_TYPE_IB = 0;

    /**
     * TYPE: in band, any peer: role, client_id, session_id, pmk optional
     * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional
     * [only permitted for RESPONDER]
     * @hide
     */
    public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;

    /**
     * TYPE: out-of-band: role, client_id, peer_mac, pmk optional
     * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional
     * @hide
     */
    public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;

    /**
     * TYPE: out-of-band, any peer: role, client_id, pmk optional
     * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional
     * [only permitted for RESPONDER]
     * @hide
     */
@@ -180,6 +180,9 @@ public class WifiAwareManager {
    /** @hide */
    public static final String NETWORK_SPECIFIER_KEY_PMK = "pmk";

    /** @hide */
    public static final String NETWORK_SPECIFIER_KEY_PASSPHRASE = "passphrase";

    /**
     * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
     * Use the {@link #isAvailable()} to query the current status.
@@ -473,11 +476,12 @@ public class WifiAwareManager {

    /** @hide */
    public String createNetworkSpecifier(int clientId, int role, int sessionId,
            PeerHandle peerHandle, @Nullable byte[] pmk) {
            PeerHandle peerHandle, @Nullable byte[] pmk, @Nullable String passphrase) {
        if (VDBG) {
            Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
                    + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
                    + ", pmk=" + ((pmk == null) ? "null" : "non-null"));
                    + ", pmk=" + ((pmk == null) ? "null" : "non-null")
                    + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
        }

        int type = (peerHandle == null) ? NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
@@ -512,6 +516,11 @@ public class WifiAwareManager {
            }
            json.put(NETWORK_SPECIFIER_KEY_PMK,
                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
            if (passphrase == null) {
                passphrase = new String();
            }
            json.put(NETWORK_SPECIFIER_KEY_PASSPHRASE, passphrase);

        } catch (JSONException e) {
            return "";
        }
@@ -521,10 +530,11 @@ public class WifiAwareManager {

    /** @hide */
    public String createNetworkSpecifier(int clientId, @DataPathRole int role,
            @Nullable byte[] peer, @Nullable byte[] pmk) {
            @Nullable byte[] peer, @Nullable byte[] pmk, @Nullable String passphrase) {
        if (VDBG) {
            Log.v(TAG, "createNetworkSpecifier: role=" + role
                    + ", pmk=" + ((pmk == null) ? "null" : "non-null"));
                    + ", pmk=" + ((pmk == null) ? "null" : "non-null")
                    + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
        }

        int type = (peer == null) ?
@@ -560,6 +570,10 @@ public class WifiAwareManager {
            }
            json.put(NETWORK_SPECIFIER_KEY_PMK,
                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
            if (passphrase == null) {
                passphrase = new String();
            }
            json.put(NETWORK_SPECIFIER_KEY_PASSPHRASE, passphrase);
        } catch (JSONException e) {
            return "";
        }
+59 −5
Original line number Diff line number Diff line
@@ -192,6 +192,9 @@ public class WifiAwareSession {
     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
     *     when using Aware discovery use the alternative network specifier method -
     *     {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)}.
     * <p>
     * To set up an encrypted link use the {@link #createNetworkSpecifierPmk(int, byte[], byte[])}
     * or {@link #createNetworkSpecifierPassphrase(int, byte[], String)} APIs.
     *
     * @param role  The role of this device:
     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
@@ -220,7 +223,56 @@ public class WifiAwareSession {
            Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
            return "";
        }
        return mgr.createNetworkSpecifier(mClientId, role, peer, null);
        return mgr.createNetworkSpecifier(mClientId, role, peer, null, null);
    }

    /**
     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
     * encrypted WiFi Aware connection (link) to the specified peer. The
     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
     * <p>
     *     This API is targeted for applications which can obtain the peer MAC address using OOB
     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
     *     when using Aware discovery use the alternative network specifier method -
     *     {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
     *
     * @param role  The role of this device:
     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
     *              value is used to gate the acceptance of a connection request from only that
     *              peer. A RESPONDER may specify a null - indicating that it will accept
     *              connection requests from any device.
     * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
     *                   the passphrase. Use the
     *                   {@link #createNetworkSpecifierPmk(int, byte[], byte[])} to specify the
     *                   PMK directly or {@link #createNetworkSpecifierOpen(int, byte[])} to
     *                   specify an open (unencrypted) link.
     *
     * @return A string to be used to construct
     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
     * android.net.ConnectivityManager.NetworkCallback)}
     * [or other varieties of that API].
     *
     * @hide
     */
    public String createNetworkSpecifierPassphrase(@WifiAwareManager.DataPathRole int role,
            @Nullable byte[] peer, @NonNull String passphrase) {
        WifiAwareManager mgr = mMgr.get();
        if (mgr == null) {
            Log.e(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
            return "";
        }
        if (mTerminated) {
            Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
            return "";
        }
        if (passphrase == null || passphrase.length() == 0) {
            throw new IllegalArgumentException("Passphrase must not be null or empty");
        }
        return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
    }

    /**
@@ -232,7 +284,7 @@ public class WifiAwareSession {
     *     This API is targeted for applications which can obtain the peer MAC address using OOB
     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
     *     when using Aware discovery use the alternative network specifier method -
     *     {@link DiscoverySession#createNetworkSpecifierPmk(PeerHandle, byte[])}}.
     *     {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
     *
     * @param role  The role of this device:
     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
@@ -242,8 +294,10 @@ public class WifiAwareSession {
     *              peer. A RESPONDER may specify a null - indicating that it will accept
     *              connection requests from any device.
     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
     *            encrypting the data-path. Use the {@link #createNetworkSpecifierOpen(int, byte[])}
     *            to specify an open (unencrypted) link.
     *            encrypting the data-path. Use the
     *            {@link #createNetworkSpecifierPassphrase(int, byte[], String)} to specify a
     *            Passphrase or {@link #createNetworkSpecifierOpen(int, byte[])} to specify an
     *            open (unencrypted) link.
     *
     * @return A string to be used to construct
     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
@@ -267,7 +321,7 @@ public class WifiAwareSession {
        if (pmk == null || pmk.length == 0) {
            throw new IllegalArgumentException("PMK must not be null or empty");
        }
        return mgr.createNetworkSpecifier(mClientId, role, peer, pmk);
        return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
    }

    /**
+34 −0
Original line number Diff line number Diff line
@@ -974,6 +974,7 @@ public class WifiAwareManagerTest {
        final PeerHandle peerHandle = new PeerHandle(123412);
        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
        final byte[] pmk = "Some arbitrary byte array".getBytes();
        final String passphrase = "A really bad password";
        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
        final PublishConfig publishConfig = new PublishConfig.Builder().build();

@@ -1038,6 +1039,23 @@ public class WifiAwareManagerTest {
        collector.checkThat("pmk", pmkB64 ,
                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));

        // (5) request an encrypted (Passphrase) network specifier from the session
        networkSpecifier = publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle,
                passphrase);

        // validate format
        jsonObject = new JSONObject(networkSpecifier);
        collector.checkThat("role", role,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
        collector.checkThat("client_id", clientId,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
        collector.checkThat("session_id", sessionId,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
        collector.checkThat("peer_id", peerHandle.peerId,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
        collector.checkThat("passphrase", passphrase,
                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));

        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                mockPublishSession, mockRttListener);
    }
@@ -1053,6 +1071,7 @@ public class WifiAwareManagerTest {
        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
        final byte[] pmk = "Some arbitrary pmk data".getBytes();
        final String passphrase = "A really bad password";

        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);

@@ -1101,6 +1120,21 @@ public class WifiAwareManagerTest {
        collector.checkThat("pmk", pmkB64,
                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));

        // (4) request an encrypted (Passphrase) direct network specifier
        networkSpecifier = session.createNetworkSpecifierPassphrase(role, someMac, passphrase);

        // validate format
        jsonObject = new JSONObject(networkSpecifier);
        collector.checkThat("role", role,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
        collector.checkThat("client_id", clientId,
                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
                false)));
        collector.checkThat("passphrase", passphrase,
                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));

        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                mockPublishSession, mockRttListener);
    }