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

Commit 2328423d authored by Casper Bonde's avatar Casper Bonde Committed by Andre Eisenbach
Browse files

Add support for MITM for BluetoothSockets (1/4)



This change adds an option to enforce Man-in-the-middle protection
for the authentication process. This feature is needed for the Sim
Access Profile.

Change-Id: Ia3ef0caeb750f88608c9fa6bf6367d1c77de4cf3
Signed-off-by: default avatarCasper Bonde <c.bonde@samsung.com>
parent b12c9704
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -1467,8 +1467,29 @@ public final class BluetoothAdapter {
     * @hide
     */
    public BluetoothServerSocket listenUsingRfcommOn(int channel) throws IOException {
        return listenUsingRfcommOn(channel, false);
    }

    /**
     * Create a listening, secure RFCOMM Bluetooth socket.
     * <p>A remote device connecting to this socket will be authenticated and
     * communication on this socket will be encrypted.
     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
     * connections from a listening {@link BluetoothServerSocket}.
     * <p>Valid RFCOMM channels are in range 1 to 30.
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
     * <p>To auto assign a channel without creating a SDP record use
     * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as channel number.
     * @param channel RFCOMM channel to listen on
     * @param mitm    enforce man-in-the-middle protection for authentication.
     * @return a listening RFCOMM BluetoothServerSocket
     * @throws IOException on error, for example Bluetooth not available, or
     *                     insufficient permissions, or channel in use.
     * @hide
     */
    public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm) throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, true, true, channel);
                BluetoothSocket.TYPE_RFCOMM, true, true, channel, mitm);
        int errno = socket.mSocket.bindListen();
        if (channel == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
            socket.setChannel(socket.mSocket.getPort());
@@ -1669,14 +1690,18 @@ public final class BluetoothAdapter {
    /**
     * Construct an encrypted, authenticated, L2CAP server socket.
     * Call #accept to retrieve connections to this socket.
     * <p>To auto assign a port without creating a SDP record use
     * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
     * @param port    the PSM to listen on
     * @param mitm    enforce man-in-the-middle protection for authentication.
     * @return An L2CAP BluetoothServerSocket
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient permissions.
     * @hide
     */
    public BluetoothServerSocket listenUsingL2capOn(int port) throws IOException {
    public BluetoothServerSocket listenUsingL2capOn(int port, boolean mitm) throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_L2CAP, true, true, port);
                BluetoothSocket.TYPE_L2CAP, true, true, port, mitm);
        int errno = socket.mSocket.bindListen();
        if(port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
            socket.setChannel(socket.mSocket.getPort());
@@ -1690,6 +1715,21 @@ public final class BluetoothAdapter {
        return socket;
    }

    /**
     * Construct an encrypted, authenticated, L2CAP server socket.
     * Call #accept to retrieve connections to this socket.
     * <p>To auto assign a port without creating a SDP record use
     * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
     * @param port    the PSM to listen on
     * @return An L2CAP BluetoothServerSocket
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient permissions.
     * @hide
     */
    public BluetoothServerSocket listenUsingL2capOn(int port) throws IOException {
        return listenUsingL2capOn(port, false);
    }

    /**
     * Read the local Out of Band Pairing Data
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+20 −0
Original line number Diff line number Diff line
@@ -91,6 +91,26 @@ public final class BluetoothServerSocket implements Closeable {
        }
    }

    /**
     * Construct a socket for incoming connections.
     * @param type    type of socket
     * @param auth    require the remote device to be authenticated
     * @param encrypt require the connection to be encrypted
     * @param port    remote port
     * @param mitm    enforce man-in-the-middle protection for authentication.
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient privileges
     */
    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port,
            boolean mitm)
            throws IOException {
        mChannel = port;
        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null, mitm);
        if(port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
            mSocket.setExcludeSdp(true);
        }
    }

    /**
     * Construct a socket for incoming connections.
     * @param type    type of socket
+26 −2
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ public final class BluetoothSocket implements Closeable {
    /*package*/ static final int SEC_FLAG_ENCRYPT = 1;
    /*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
    /*package*/ static final int BTSOCK_FLAG_NO_SDP  = 1 << 2;
    /*package*/ static final int SEC_FLAG_AUTH_MITM  = 1 << 3;

    private final int mType;  /* one of TYPE_RFCOMM etc */
    private BluetoothDevice mDevice;    /* remote device */
@@ -115,7 +116,8 @@ public final class BluetoothSocket implements Closeable {
    private final BluetoothInputStream mInputStream;
    private final BluetoothOutputStream mOutputStream;
    private final ParcelUuid mUuid;
    private boolean mExcludeSdp = false;
    private boolean mExcludeSdp = false; /* when true no SPP SDP record will be created */
    private boolean mAuthMitm = false;   /* when true Man-in-the-middle protection will be enabled*/
    private ParcelFileDescriptor mPfd;
    private LocalSocket mSocket;
    private InputStream mSocketIS;
@@ -158,6 +160,24 @@ public final class BluetoothSocket implements Closeable {
     */
    /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
            BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
        this(type, fd, auth, encrypt, device, port, uuid, false);
    }

    /**
     * Construct a BluetoothSocket.
     * @param type    type of socket
     * @param fd      fd to use for connected socket, or -1 for a new socket
     * @param auth    require the remote device to be authenticated
     * @param encrypt require the connection to be encrypted
     * @param device  remote device that this socket can connect to
     * @param port    remote port
     * @param uuid    SDP uuid
     * @param mitm    enforce man-in-the-middle protection.
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient privileges
     */
    /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
            BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm) throws IOException {
        if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
        if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
                && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
@@ -170,6 +190,7 @@ public final class BluetoothSocket implements Closeable {
        else mUuid = new ParcelUuid(new UUID(0, 0));
        mType = type;
        mAuth = auth;
        mAuthMitm = mitm;
        mEncrypt = encrypt;
        mDevice = device;
        mPort = port;
@@ -201,6 +222,7 @@ public final class BluetoothSocket implements Closeable {

        mServiceName = s.mServiceName;
        mExcludeSdp = s.mExcludeSdp;
        mAuthMitm = s.mAuthMitm;
    }
    private BluetoothSocket acceptSocket(String RemoteAddr) throws IOException {
        BluetoothSocket as = new BluetoothSocket(this);
@@ -232,7 +254,7 @@ public final class BluetoothSocket implements Closeable {
     */
    private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
            int port) throws IOException {
        this(type, fd, auth, encrypt, new BluetoothDevice(address), port, null);
        this(type, fd, auth, encrypt, new BluetoothDevice(address), port, null, false);
    }

    /** @hide */
@@ -252,6 +274,8 @@ public final class BluetoothSocket implements Closeable {
            flags |= SEC_FLAG_ENCRYPT;
        if(mExcludeSdp)
            flags |= BTSOCK_FLAG_NO_SDP;
        if(mAuthMitm)
            flags |= SEC_FLAG_AUTH_MITM;
        return flags;
    }