From 168b16527c4344ab4bccc9da0157f9ea6b2b981c Mon Sep 17 00:00:00 2001 From: Albert Vaca Cintora Date: Wed, 17 Apr 2019 20:24:50 +0200 Subject: [PATCH] Remove compat with protocol 6 with RSA encryption Since we already removed compat with protocol 7 ^.^u --- src/org/kde/kdeconnect/Backends/BaseLink.java | 3 - .../BluetoothBackend/BluetoothLink.java | 30 +----- .../BluetoothPairingHandler.java | 2 +- .../Backends/LanBackend/LanLink.java | 48 ++------- .../Backends/LanBackend/LanLinkProvider.java | 97 ++++++++----------- .../LanBackend/LanPairingHandler.java | 26 +---- .../LoopbackBackend/LoopbackLink.java | 6 -- .../LoopbackPairingHandler.java | 2 +- src/org/kde/kdeconnect/Device.java | 38 +------- .../Helpers/SecurityHelpers/RsaHelper.java | 62 ------------ .../Helpers/SecurityHelpers/SslHelper.java | 5 - src/org/kde/kdeconnect/NetworkPacket.java | 2 - src/org/kde/kdeconnect/Plugins/Plugin.java | 16 --- .../Plugins/SftpPlugin/AndroidSafSshFile.java | 2 +- .../Plugins/SftpPlugin/RootFile.java | 2 +- .../Plugins/SftpPlugin/SimpleSftpServer.java | 7 +- tests/org/kde/kdeconnect/DeviceTest.java | 2 +- tests/org/kde/kdeconnect/LanLinkTest.java | 6 +- 18 files changed, 64 insertions(+), 292 deletions(-) diff --git a/src/org/kde/kdeconnect/Backends/BaseLink.java b/src/org/kde/kdeconnect/Backends/BaseLink.java index 18c468db..a238a389 100644 --- a/src/org/kde/kdeconnect/Backends/BaseLink.java +++ b/src/org/kde/kdeconnect/Backends/BaseLink.java @@ -26,7 +26,6 @@ import org.kde.kdeconnect.Device; import org.kde.kdeconnect.NetworkPacket; import java.security.PrivateKey; -import java.security.PublicKey; import java.util.ArrayList; @@ -90,6 +89,4 @@ public abstract class BaseLink { //TO OVERRIDE, should be sync public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback); - @Deprecated - public abstract boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key); } diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java index 4a857130..33f972f9 100644 --- a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java @@ -32,7 +32,6 @@ import org.json.JSONObject; import org.kde.kdeconnect.Backends.BaseLink; import org.kde.kdeconnect.Backends.BasePairingHandler; import org.kde.kdeconnect.Device; -import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper; import org.kde.kdeconnect.NetworkPacket; import java.io.IOException; @@ -41,7 +40,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.nio.charset.Charset; -import java.security.PublicKey; import java.util.UUID; public class BluetoothLink extends BaseLink { @@ -87,14 +85,6 @@ public class BluetoothLink extends BaseLink { return; } - if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) { - try { - np = RsaHelper.decrypt(np, privateKey); - } catch (Exception e) { - Log.e("BluetoothLink/receiving", "Exception decrypting the package", e); - } - } - if (np.hasPayloadTransferInfo()) { BluetoothSocket transferSocket = null; try { @@ -158,16 +148,7 @@ public class BluetoothLink extends BaseLink { } @Override - public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) { - return sendPacketInternal(np, callback, null); - } - - @Override - public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) { - return sendPacketInternal(np, callback, key); - } - - private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) { + public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) { /*if (!isConnected()) { Log.e("BluetoothLink", "sendPacketEncrypted failed: not connected"); @@ -186,15 +167,6 @@ public class BluetoothLink extends BaseLink { np.setPayloadTransferInfo(payloadTransferInfo); } - if (key != null) { - try { - np = RsaHelper.encrypt(np, key); - } catch (Exception e) { - callback.onFailure(e); - return false; - } - } - sendMessage(np); if (serverSocket != null) { diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java index d5743357..d86de46e 100644 --- a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java @@ -52,7 +52,7 @@ public class BluetoothPairingHandler extends BasePairingHandler { } @Override - public void packageReceived(NetworkPacket np) throws Exception { + public void packageReceived(NetworkPacket np) { boolean wantsPair = np.getBoolean("pair"); diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java index 0a5485ec..f4847fa0 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java @@ -27,7 +27,6 @@ import org.json.JSONObject; import org.kde.kdeconnect.Backends.BaseLink; import org.kde.kdeconnect.Backends.BasePairingHandler; import org.kde.kdeconnect.Device; -import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Helpers.StringsHelper; import org.kde.kdeconnect.NetworkPacket; @@ -42,7 +41,6 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.channels.NotYetConnectedException; -import java.security.PublicKey; import javax.net.ssl.SSLSocket; @@ -61,7 +59,7 @@ public class LanLink extends BaseLink { // because it's probably trying to find me and // potentially ask for pairing. - private volatile Socket socket = null; + private volatile SSLSocket socket = null; private final LinkDisconnectedCallback callback; @@ -76,9 +74,9 @@ public class LanLink extends BaseLink { } //Returns the old socket - public Socket reset(final Socket newSocket, ConnectionStarted connectionSource) throws IOException { + public SSLSocket reset(final SSLSocket newSocket, ConnectionStarted connectionSource) throws IOException { - Socket oldSocket = socket; + SSLSocket oldSocket = socket; socket = newSocket; this.connectionSource = connectionSource; @@ -121,7 +119,7 @@ public class LanLink extends BaseLink { return oldSocket; } - public LanLink(Context context, String deviceId, LanLinkProvider linkProvider, Socket socket, ConnectionStarted connectionSource) throws IOException { + public LanLink(Context context, String deviceId, LanLinkProvider linkProvider, SSLSocket socket, ConnectionStarted connectionSource) throws IOException { super(context, deviceId, linkProvider); callback = linkProvider; reset(socket, connectionSource); @@ -139,7 +137,8 @@ public class LanLink extends BaseLink { } //Blocking, do not call from main thread - private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) { + @Override + public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) { if (socket == null) { Log.e("KDE/sendPacket", "Not yet connected"); callback.onFailure(new NotYetConnectedException()); @@ -159,11 +158,6 @@ public class LanLink extends BaseLink { server = null; } - //Encrypt if key provided - if (key != null) { - np = RsaHelper.encrypt(np, key); - } - //Log.e("LanLink/sendPacket", np.getType()); //Send body of the network package @@ -188,9 +182,7 @@ public class LanLink extends BaseLink { payloadSocket = server.accept(); //Convert to SSL if needed - if (socket instanceof SSLSocket) { - payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, false); - } + payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, false); outputStream = payloadSocket.getOutputStream(); inputStream = np.getPayload().getInputStream(); @@ -240,39 +232,15 @@ public class LanLink extends BaseLink { } } - - //Blocking, do not call from main thread - @Override - public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) { - return sendPacketInternal(np, callback, null); - } - - //Blocking, do not call from main thread - @Override - public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) { - return sendPacketInternal(np, callback, key); - } - private void receivedNetworkPacket(NetworkPacket np) { - if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) { - try { - np = RsaHelper.decrypt(np, privateKey); - } catch(Exception e) { - Log.e("KDE/onPacketReceived","Exception decrypting the package", e); - } - } - if (np.hasPayloadTransferInfo()) { Socket payloadSocket = new Socket(); try { int tcpPort = np.getPayloadTransferInfo().getInt("port"); InetSocketAddress deviceAddress = (InetSocketAddress) socket.getRemoteSocketAddress(); payloadSocket.connect(new InetSocketAddress(deviceAddress.getAddress(), tcpPort)); - // Use ssl if existing link is on ssl - if (socket instanceof SSLSocket) { - payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, true); - } + payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, true); np.setPayload(new NetworkPacket.Payload(payloadSocket, np.getPayloadSize())); } catch (Exception e) { try { payloadSocket.close(); } catch(Exception ignored) { } diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java index 74a93555..b2d539fd 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java @@ -66,9 +66,6 @@ import javax.net.ssl.SSLSocket; */ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDisconnectedCallback { - public static final int MIN_VERSION_WITH_SSL_SUPPORT = 6; - private static final int MIN_VERSION_WITH_NEW_PORT_SUPPORT = 7; - private final static int MIN_PORT = 1716; private final static int MAX_PORT = 1764; final static int PAYLOAD_TRANSFER_MIN_PORT = 1739; @@ -93,7 +90,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis } //They received my UDP broadcast and are connecting to me. The first thing they sned should be their identity. - private void tcpPacketReceived(Socket socket) throws Exception { + private void tcpPacketReceived(Socket socket) { NetworkPacket networkPacket; try { @@ -116,7 +113,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis } //I've received their broadcast and should connect to their TCP socket and send my identity. - private void udpPacketReceived(DatagramPacket packet) throws Exception { + private void udpPacketReceived(DatagramPacket packet) { final InetAddress address = packet.getAddress(); @@ -136,11 +133,6 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis } } - if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPacket.getInt("tcpPort") < MIN_PORT) { - Log.w("KDE/LanLinkProvider", "Ignoring a udp broadcast from legacy port because it comes from a device which knows about the new port."); - return; - } - Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPacket.getString("deviceName")); int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT); @@ -206,61 +198,56 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis // If I'm the TCP server I will be the SSL client and viceversa. final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally); - // Add ssl handler if device uses new protocol + // Do the SSL handshake try { - if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) { + SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE); + boolean isDeviceTrusted = preferences.getBoolean(deviceId, false); - SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE); - boolean isDeviceTrusted = preferences.getBoolean(deviceId, false); + if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) { + //Device paired with and old version, we can't use it as we lack the certificate + BackgroundService.RunCommand(context, service -> { + Device device = service.getDevice(deviceId); + if (device == null) return; + device.unpair(); + //Retry as unpaired + identityPacketReceived(identityPacket, socket, connectionStarted); + }); + } - if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) { - //Device paired with and old version, we can't use it as we lack the certificate + Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted); + + final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode); + sslsocket.addHandshakeCompletedListener(event -> { + String mode = clientMode ? "client" : "server"; + try { + Certificate certificate = event.getPeerCertificates()[0]; + identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0)); + Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite()); + addLink(identityPacket, sslsocket, connectionStarted); + } catch (Exception e) { + Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e); BackgroundService.RunCommand(context, service -> { Device device = service.getDevice(deviceId); if (device == null) return; device.unpair(); - //Retry as unpaired - identityPacketReceived(identityPacket, socket, connectionStarted); }); } - - Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted); - - final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode); - sslsocket.addHandshakeCompletedListener(event -> { - String mode = clientMode ? "client" : "server"; - try { - Certificate certificate = event.getPeerCertificates()[0]; - identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0)); - Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite()); - addLink(identityPacket, sslsocket, connectionStarted); - } catch (Exception e) { - Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e); - BackgroundService.RunCommand(context, service -> { - Device device = service.getDevice(deviceId); - if (device == null) return; - device.unpair(); - }); + }); + //Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection + new Thread(() -> { + try { + synchronized (this) { + sslsocket.startHandshake(); } - }); - //Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection - new Thread(() -> { - try { - synchronized (this) { - sslsocket.startHandshake(); - } - } catch (Exception e) { - Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"), e); + } catch (Exception e) { + Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"), e); - //String[] ciphers = sslsocket.getSupportedCipherSuites(); - //for (String cipher : ciphers) { - // Log.i("SupportedCiphers","cipher: " + cipher); - //} - } - }).start(); - } else { - addLink(identityPacket, socket, connectionStarted); - } + //String[] ciphers = sslsocket.getSupportedCipherSuites(); + //for (String cipher : ciphers) { + // Log.i("SupportedCiphers","cipher: " + cipher); + //} + } + }).start(); } catch (Exception e) { Log.e("LanLink", "Exception", e); } @@ -280,7 +267,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis * @param connectionOrigin which side started this connection * @throws IOException if an exception is thrown by {@link LanLink#reset(Socket, LanLink.ConnectionStarted)} */ - private void addLink(final NetworkPacket identityPacket, Socket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException { + private void addLink(final NetworkPacket identityPacket, SSLSocket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException { String deviceId = identityPacket.getString("deviceId"); LanLink currentLink = visibleComputers.get(deviceId); diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java index 049efa93..4a6906af 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java @@ -22,7 +22,6 @@ package org.kde.kdeconnect.Backends.LanBackend; import android.content.Context; import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.util.Base64; import android.util.Log; @@ -31,9 +30,7 @@ import org.kde.kdeconnect.Device; import org.kde.kdeconnect.NetworkPacket; import org.kde.kdeconnect_tp.R; -import java.security.KeyFactory; import java.security.cert.CertificateEncodingException; -import java.security.spec.X509EncodedKeySpec; import java.util.Timer; import java.util.TimerTask; @@ -54,14 +51,11 @@ public class LanPairingHandler extends BasePairingHandler { private NetworkPacket createPairPacket() { NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR); np.set("pair", true); - SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(mDevice.getContext()); - String publicKey = "-----BEGIN PUBLIC KEY-----\n" + globalSettings.getString("publicKey", "").trim()+ "\n-----END PUBLIC KEY-----\n"; - np.set("publicKey", publicKey); return np; } @Override - public void packageReceived(NetworkPacket np) throws Exception{ + public void packageReceived(NetworkPacket np) { boolean wantsPair = np.getBoolean("pair"); @@ -77,15 +71,6 @@ public class LanPairingHandler extends BasePairingHandler { if (wantsPair) { - //Retrieve their public key - try { - String publicKeyContent = np.getString("publicKey").replace("-----BEGIN PUBLIC KEY-----\n","").replace("-----END PUBLIC KEY-----\n", ""); - byte[] publicKeyBytes = Base64.decode(publicKeyContent, 0); - mDevice.publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); - } catch (Exception e) { - //IGNORE - } - if (mPairStatus == PairStatus.Requested) { //We started pairing hidePairingNotification(); @@ -204,15 +189,6 @@ public class LanPairingHandler extends BasePairingHandler { //Log.e("KDE/PairingDone", "Pairing Done"); SharedPreferences.Editor editor = mDevice.getContext().getSharedPreferences(mDevice.getDeviceId(), Context.MODE_PRIVATE).edit(); - if (mDevice.publicKey != null) { - try { - String encodedPublicKey = Base64.encodeToString(mDevice.publicKey.getEncoded(), 0); - editor.putString("publicKey", encodedPublicKey); - } catch (Exception e) { - Log.e("KDE/PairingDone", "Error encoding public key", e); - } - } - try { String encodedCertificate = Base64.encodeToString(mDevice.certificate.getEncoded(), 0); editor.putString("certificate", encodedCertificate); diff --git a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java index 72c94692..bb8bef66 100644 --- a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java +++ b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java @@ -28,8 +28,6 @@ import org.kde.kdeconnect.Backends.BasePairingHandler; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.NetworkPacket; -import java.security.PublicKey; - public class LoopbackLink extends BaseLink { public LoopbackLink(Context context, BaseLinkProvider linkProvider) { @@ -58,8 +56,4 @@ public class LoopbackLink extends BaseLink { return true; } - @Override - public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) { - return sendPacket(np, callback); - } } diff --git a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackPairingHandler.java b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackPairingHandler.java index 8b8c0d4c..6d1e0746 100644 --- a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackPairingHandler.java +++ b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackPairingHandler.java @@ -33,7 +33,7 @@ public class LoopbackPairingHandler extends BasePairingHandler { } @Override - public void packageReceived(NetworkPacket np) throws Exception { + public void packageReceived(NetworkPacket np) { } diff --git a/src/org/kde/kdeconnect/Device.java b/src/org/kde/kdeconnect/Device.java index 811379e9..a0b2dcd2 100644 --- a/src/org/kde/kdeconnect/Device.java +++ b/src/org/kde/kdeconnect/Device.java @@ -35,7 +35,6 @@ import android.util.Log; import org.kde.kdeconnect.Backends.BaseLink; import org.kde.kdeconnect.Backends.BasePairingHandler; -import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider; import org.kde.kdeconnect.Helpers.NotificationHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Plugins.Plugin; @@ -45,10 +44,8 @@ import org.kde.kdeconnect_tp.R; import java.security.KeyFactory; import java.security.PrivateKey; -import java.security.PublicKey; import java.security.cert.Certificate; import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -68,7 +65,6 @@ public class Device implements BaseLink.PacketReceiver { private final String deviceId; private String name; - public PublicKey publicKey; public Certificate certificate; private int notificationId; private int protocolVersion; @@ -150,16 +146,6 @@ public class Device implements BaseLink.PacketReceiver { this.protocolVersion = NetworkPacket.ProtocolVersion; //We don't know it yet this.deviceType = DeviceType.FromString(settings.getString("deviceType", "desktop")); - try { - String publicKeyStr = settings.getString("publicKey", null); - if (publicKeyStr != null) { - byte[] publicKeyBytes = Base64.decode(publicKeyStr, 0); - publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); - } - } catch (Exception e) { - Log.e("KDE/Device", "Exception deserializing stored public key for device", e); - } - //Assume every plugin is supported until addLink is called and we can get the actual list m_supportedPlugins = new Vector<>(PluginFactory.getAvailablePlugins()); @@ -178,7 +164,6 @@ public class Device implements BaseLink.PacketReceiver { this.pairStatus = PairStatus.NotPaired; this.protocolVersion = 0; this.deviceType = DeviceType.Computer; - this.publicKey = null; settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE); @@ -546,8 +531,6 @@ public class Device implements BaseLink.PacketReceiver { @Override public void onPacketReceived(NetworkPacket np) { - hackToMakeRetrocompatiblePacketTypes(np); - if (NetworkPacket.PACKET_TYPE_PAIR.equals(np.getType())) { Log.i("KDE/Device", "Pair package"); @@ -651,20 +634,12 @@ public class Device implements BaseLink.PacketReceiver { } */ - hackToMakeRetrocompatiblePacketTypes(np); - - boolean useEncryption = (protocolVersion < LanLinkProvider.MIN_VERSION_WITH_SSL_SUPPORT && (!np.getType().equals(NetworkPacket.PACKET_TYPE_PAIR) && isPaired())); - boolean success = false; //Make a copy to avoid concurrent modification exception if the original list changes for (final BaseLink link : links) { if (link == null) continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile - if (useEncryption) { - success = link.sendPacketEncrypted(np, callback, publicKey); - } else { - success = link.sendPacket(np, callback); - } + success = link.sendPacket(np, callback); if (success) break; //If the link didn't call sendSuccess(), try the next one } @@ -796,7 +771,6 @@ public class Device implements BaseLink.PacketReceiver { boolean success = addPlugin(pluginKey); if (success) { for (String packageType : pluginInfo.getSupportedPacketTypes()) { - packageType = hackToMakeRetrocompatiblePacketTypes(packageType); ArrayList plugins = newPluginsByIncomingInterface.get(packageType); if (plugins == null) plugins = new ArrayList<>(); plugins.add(pluginKey); @@ -866,14 +840,4 @@ public class Device implements BaseLink.PacketReceiver { return m_supportedPlugins; } - private void hackToMakeRetrocompatiblePacketTypes(NetworkPacket np) { - if (protocolVersion >= 6) return; - np.mType = np.getType().replace(".request", ""); - } - - private String hackToMakeRetrocompatiblePacketTypes(String type) { - if (protocolVersion >= 6) return type; - return type.replace(".request", ""); - } - } diff --git a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java index 3244f375..40bd1e0b 100644 --- a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java @@ -26,11 +26,6 @@ import android.preference.PreferenceManager; import android.util.Base64; import android.util.Log; -import org.json.JSONArray; -import org.json.JSONException; -import org.kde.kdeconnect.NetworkPacket; - -import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; @@ -40,8 +35,6 @@ import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; -import javax.crypto.Cipher; - public class RsaHelper { public static void initialiseRsaKeys(Context context) { @@ -77,67 +70,12 @@ public class RsaHelper { return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); } - public static PublicKey getPublicKey(Context context, String deviceId) throws GeneralSecurityException { - SharedPreferences settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE); - byte[] publicKeyBytes = Base64.decode(settings.getString("publicKey", ""), 0); - return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); - } - public static PrivateKey getPrivateKey(Context context) throws GeneralSecurityException { SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context); byte[] privateKeyBytes = Base64.decode(globalSettings.getString("privateKey", ""), 0); return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); } - public static NetworkPacket encrypt(NetworkPacket np, PublicKey publicKey) throws GeneralSecurityException, JSONException { - - String serialized = np.serialize(); - - int chunkSize = 128; - - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - - JSONArray chunks = new JSONArray(); - while (serialized.length() > 0) { - if (serialized.length() < chunkSize) { - chunkSize = serialized.length(); - } - String chunk = serialized.substring(0, chunkSize); - serialized = serialized.substring(chunkSize); - byte[] chunkBytes = chunk.getBytes(Charset.defaultCharset()); - byte[] encryptedChunk; - encryptedChunk = cipher.doFinal(chunkBytes); - chunks.put(Base64.encodeToString(encryptedChunk, Base64.NO_WRAP)); - } - - //Log.i("NetworkPacket", "Encrypted " + chunks.length()+" chunks"); - - NetworkPacket encrypted = new NetworkPacket(NetworkPacket.PACKET_TYPE_ENCRYPTED); - encrypted.set("data", chunks); - encrypted.setPayload(np.getPayload()); - return encrypted; - - } - - public static NetworkPacket decrypt(NetworkPacket np, PrivateKey privateKey) throws GeneralSecurityException, JSONException { - - JSONArray chunks = np.getJSONArray("data"); - - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - - StringBuilder decryptedJson = new StringBuilder(); - for (int i = 0; i < chunks.length(); i++) { - byte[] encryptedChunk = Base64.decode(chunks.getString(i), Base64.NO_WRAP); - String decryptedChunk = new String(cipher.doFinal(encryptedChunk)); - decryptedJson.append(decryptedChunk); - } - - NetworkPacket decrypted = NetworkPacket.unserialize(decryptedJson.toString()); - decrypted.setPayload(np.getPayload()); - return decrypted; - } } diff --git a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java index 98b96074..84349838 100644 --- a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java @@ -65,11 +65,6 @@ import javax.net.ssl.X509TrustManager; public class SslHelper { - public enum SslMode { - Client, - Server - } - public static X509Certificate certificate; //my device's certificate public static final BouncyCastleProvider BC = new BouncyCastleProvider(); diff --git a/src/org/kde/kdeconnect/NetworkPacket.java b/src/org/kde/kdeconnect/NetworkPacket.java index 87ccdc07..84824acd 100644 --- a/src/org/kde/kdeconnect/NetworkPacket.java +++ b/src/org/kde/kdeconnect/NetworkPacket.java @@ -44,12 +44,10 @@ public class NetworkPacket { public final static String PACKET_TYPE_IDENTITY = "kdeconnect.identity"; public final static String PACKET_TYPE_PAIR = "kdeconnect.pair"; - public final static String PACKET_TYPE_ENCRYPTED = "kdeconnect.encrypted"; public static Set protocolPacketTypes = new HashSet() {{ add(PACKET_TYPE_IDENTITY); add(PACKET_TYPE_PAIR); - add(PACKET_TYPE_ENCRYPTED); }}; private long mId; diff --git a/src/org/kde/kdeconnect/Plugins/Plugin.java b/src/org/kde/kdeconnect/Plugins/Plugin.java index 9a9e3ab9..d07a56bd 100644 --- a/src/org/kde/kdeconnect/Plugins/Plugin.java +++ b/src/org/kde/kdeconnect/Plugins/Plugin.java @@ -25,7 +25,6 @@ import android.content.Context; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Build; -import android.widget.Button; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.NetworkPacket; @@ -185,21 +184,6 @@ public abstract class Plugin { */ public abstract String[] getOutgoingPacketTypes(); - /** - * Creates a button that will be displayed in the user interface - * It can open an activity or perform any other action that the - * plugin would wants to expose to the user. Return null if no - * button should be displayed. - */ - @Deprecated - public Button getInterfaceButton(final Activity activity) { - if (!hasMainActivity()) return null; - Button b = new Button(activity); - b.setText(getActionName()); - b.setOnClickListener(view -> startMainActivity(activity)); - return b; - } - protected String[] getRequiredPermissions() { return new String[0]; } diff --git a/src/org/kde/kdeconnect/Plugins/SftpPlugin/AndroidSafSshFile.java b/src/org/kde/kdeconnect/Plugins/SftpPlugin/AndroidSafSshFile.java index 9901a4a6..30a2a712 100644 --- a/src/org/kde/kdeconnect/Plugins/SftpPlugin/AndroidSafSshFile.java +++ b/src/org/kde/kdeconnect/Plugins/SftpPlugin/AndroidSafSshFile.java @@ -310,7 +310,7 @@ public class AndroidSafSshFile implements SshFile { } @Override - public Map getAttributes(boolean followLinks) throws IOException { + public Map getAttributes(boolean followLinks) { Map attributes = new HashMap<>(); for (SshFile.Attribute attr : SshFile.Attribute.values()) { switch (attr) { diff --git a/src/org/kde/kdeconnect/Plugins/SftpPlugin/RootFile.java b/src/org/kde/kdeconnect/Plugins/SftpPlugin/RootFile.java index 17236c25..a6eea5dc 100644 --- a/src/org/kde/kdeconnect/Plugins/SftpPlugin/RootFile.java +++ b/src/org/kde/kdeconnect/Plugins/SftpPlugin/RootFile.java @@ -53,7 +53,7 @@ class RootFile implements SshFile { return "/"; } - public Map getAttributes(boolean followLinks) throws IOException { + public Map getAttributes(boolean followLinks) { Map attrs = new HashMap<>(); attrs.put(Attribute.Size, 0); diff --git a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java index e6184848..e56b6cfc 100644 --- a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java +++ b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java @@ -95,11 +95,8 @@ class SimpleSftpServer { sshd.setCommandFactory(new ScpCommandFactory()); sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystem.Factory())); - if (device.publicKey != null) { - keyAuth.deviceKey = device.publicKey; - } else { - keyAuth.deviceKey = device.certificate.getPublicKey(); - } + keyAuth.deviceKey = device.certificate.getPublicKey(); + sshd.setPublickeyAuthenticator(keyAuth); sshd.setPasswordAuthenticator(passwordAuth); } diff --git a/tests/org/kde/kdeconnect/DeviceTest.java b/tests/org/kde/kdeconnect/DeviceTest.java index 1a880a24..b0e8ef0f 100644 --- a/tests/org/kde/kdeconnect/DeviceTest.java +++ b/tests/org/kde/kdeconnect/DeviceTest.java @@ -195,7 +195,7 @@ public class DeviceTest { } @Test - public void testPairingDoneWithCertificate() throws Exception { + public void testPairingDoneWithCertificate() { KeyPair keyPair = null; try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); diff --git a/tests/org/kde/kdeconnect/LanLinkTest.java b/tests/org/kde/kdeconnect/LanLinkTest.java index 79420c48..d51e627a 100644 --- a/tests/org/kde/kdeconnect/LanLinkTest.java +++ b/tests/org/kde/kdeconnect/LanLinkTest.java @@ -43,6 +43,8 @@ import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; +import javax.net.ssl.SSLSocket; + import static org.junit.Assert.assertEquals; @RunWith(PowerMockRunner.class) @@ -71,11 +73,11 @@ public class LanLinkTest { Mockito.doThrow(new IOException("AAA")).when(badOutputStream).write(Mockito.any(byte[].class)); - Socket socketMock = Mockito.mock(Socket.class); + SSLSocket socketMock = Mockito.mock(SSLSocket.class); Mockito.when(socketMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000)); Mockito.when(socketMock.getOutputStream()).thenReturn(goodOutputStream); - Socket socketBadMock = Mockito.mock(Socket.class); + SSLSocket socketBadMock = Mockito.mock(SSLSocket.class); Mockito.when(socketBadMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000)); Mockito.when(socketBadMock.getOutputStream()).thenReturn(badOutputStream);