diff options
| author | Casper Bonde <c.bonde@samsung.com> | 2015-04-21 13:12:05 +0200 |
|---|---|---|
| committer | Andre Eisenbach <eisenbach@google.com> | 2015-06-03 03:52:35 +0000 |
| commit | 26d91e282b167b50b59a8c3a956b131024a45d4a (patch) | |
| tree | 5d4b30b598ca00ad976702c0e5ba9a861c1a07de /core/java | |
| parent | 1f715be48fc33a0de57f5a0accc367857d51ce39 (diff) | |
DO NOT MERGE - 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: Casper Bonde <c.bonde@samsung.com>
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 48 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothServerSocket.java | 20 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothSocket.java | 28 |
3 files changed, 90 insertions, 6 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index b2519ca700e6..308c4c84e3a4 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1430,10 +1430,31 @@ 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) { + if (channel == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) { socket.setChannel(socket.mSocket.getPort()); } if (errno != 0) { @@ -1630,14 +1651,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()); @@ -1652,6 +1677,21 @@ 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 + * @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} * diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java index 21024a6021b0..a80f55c0e497 100644 --- a/core/java/android/bluetooth/BluetoothServerSocket.java +++ b/core/java/android/bluetooth/BluetoothServerSocket.java @@ -86,6 +86,26 @@ public final class BluetoothServerSocket implements Closeable { throws IOException { mChannel = port; mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null); + if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) { + mSocket.setExcludeSdp(true); + } + } + + /** + * 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); } diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 5702d117b66c..4722d0131021 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -102,6 +102,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 */ @@ -111,7 +112,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; @@ -154,6 +156,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) { @@ -166,6 +186,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; @@ -197,6 +218,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); @@ -228,7 +250,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 */ @@ -248,6 +270,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; } |
