diff --git a/build.gradle b/build.gradle index b0214fe6..48330169 100644 --- a/build.gradle +++ b/build.gradle @@ -52,12 +52,12 @@ dependencies { compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' compile 'org.apache.sshd:sshd-core:0.8.0' - compile 'io.netty:netty-all:4.0.23.Final' + compile 'io.netty:netty-all:4.0.29.Final' compile 'org.bouncycastle:bcpkix-jdk15on:1.52' + compile fileTree(dir: 'libs', include: '*.jar') + androidTestCompile 'org.mockito:mockito-core:1.10.19' // Because mockito has some problems with dex environment androidTestCompile 'com.google.dexmaker:dexmaker:1.1' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1' - - //compile fileTree(dir: 'libs', include: '*.jar') } diff --git a/libs/conscrypt.jar b/libs/conscrypt.jar new file mode 100644 index 00000000..a70dd00a Binary files /dev/null and b/libs/conscrypt.jar differ diff --git a/libs/conscrypt_jni.jar b/libs/conscrypt_jni.jar new file mode 100644 index 00000000..1fffe43b Binary files /dev/null and b/libs/conscrypt_jni.jar differ diff --git a/src/org/kde/kdeconnect/Backends/BaseLinkProvider.java b/src/org/kde/kdeconnect/Backends/BaseLinkProvider.java index 5de4fc9a..4bbaf2cf 100644 --- a/src/org/kde/kdeconnect/Backends/BaseLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/BaseLinkProvider.java @@ -30,7 +30,11 @@ import java.util.ArrayList; public abstract class BaseLinkProvider { private final ArrayList connectionReceivers = new ArrayList(); - public BasePairingHandler pairingHandler; + protected BasePairingHandler pairingHandler; + + public BasePairingHandler getPairingHandler() { + return pairingHandler; + } public interface ConnectionReceiver { public void onConnectionReceived(NetworkPackage identityPackage, BaseLink link); diff --git a/src/org/kde/kdeconnect/Backends/BasePairingHandler.java b/src/org/kde/kdeconnect/Backends/BasePairingHandler.java index dfa989b3..29f0c7c2 100644 --- a/src/org/kde/kdeconnect/Backends/BasePairingHandler.java +++ b/src/org/kde/kdeconnect/Backends/BasePairingHandler.java @@ -23,13 +23,13 @@ package org.kde.kdeconnect.Backends; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.NetworkPackage; -public abstract class BasePairingHandler { +public interface BasePairingHandler { - public void packageReceived(Device device, NetworkPackage np) throws Exception{} - public void requestPairing(Device device, NetworkPackage np) {} - public void accept_pairing(Device device, NetworkPackage np) {} - public void rejectPairing(Device device, NetworkPackage np) {} - public void pairingDone(Device device) {} - public void unpair(Device device, NetworkPackage np) {} + void packageReceived(Device device, NetworkPackage np) throws Exception; + void requestPairing(Device device, NetworkPackage np); + void acceptPairing(Device device, NetworkPackage np); + void rejectPairing(Device device, NetworkPackage np); + void pairingDone(Device device); + void unpair(Device device, NetworkPackage np); } diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java index 21ce9f01..46364411 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java @@ -171,7 +171,6 @@ public class LanLink extends BaseLink { public void injectNetworkPackage(NetworkPackage np) { if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) { - try { np = RsaHelper.decrypt(np, privateKey); } catch(Exception e) { diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java index 8bb478c9..30731b4b 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java @@ -57,7 +57,6 @@ import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.SocketChannelConfig; import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; @@ -144,6 +143,7 @@ public class LanLinkProvider extends BaseLinkProvider { // Log.e("LanLinkProvider","Incoming package, address: " + ctx.channel().remoteAddress()); // Log.e("LanLinkProvider","Received:"+message); + if (message.isEmpty()) { Log.e("KDE/LanLinkProvider", "Empty package received"); return; @@ -168,6 +168,7 @@ public class LanLinkProvider extends BaseLinkProvider { try { if (NetworkPackage.ProtocolVersion <= np.getInt("protocolVersion")) { final SSLEngine sslEngine = SslHelper.getSslEngine(context, np.getString("deviceId"), SslHelper.SslMode.Client); + SslHandler sslHandler = new SslHandler(sslEngine); ctx.channel().pipeline().addFirst(sslHandler); sslHandler.handshakeFuture().addListener(new GenericFutureListener>() { diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java index 3def7da8..1812fcb6 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanPairingHandler.java @@ -35,7 +35,7 @@ import java.security.KeyFactory; import java.security.cert.CertificateEncodingException; import java.security.spec.X509EncodedKeySpec; -public class LanPairingHandler extends BasePairingHandler{ +public class LanPairingHandler implements BasePairingHandler { @Override public void packageReceived(Device device, NetworkPackage np) throws Exception{ @@ -58,12 +58,17 @@ public class LanPairingHandler extends BasePairingHandler{ } @Override - public void accept_pairing(Device device, NetworkPackage np) { + public void acceptPairing(Device device, NetworkPackage np) { SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(device.getContext()); String publicKey = "-----BEGIN PUBLIC KEY-----\n" + globalSettings.getString("publicKey", "").trim()+ "\n-----END PUBLIC KEY-----\n"; np.set("publicKey", publicKey); } + @Override + public void rejectPairing(Device device, NetworkPackage np) { + + } + @Override public void pairingDone(Device device) { //Store device information needed to create a Device object in a future @@ -87,4 +92,9 @@ public class LanPairingHandler extends BasePairingHandler{ editor.apply(); } + + @Override + public void unpair(Device device, NetworkPackage np) { + + } } diff --git a/src/org/kde/kdeconnect/BackgroundService.java b/src/org/kde/kdeconnect/BackgroundService.java index 75afa8cc..18e23fe5 100644 --- a/src/org/kde/kdeconnect/BackgroundService.java +++ b/src/org/kde/kdeconnect/BackgroundService.java @@ -30,6 +30,7 @@ import android.os.IBinder; import android.preference.PreferenceManager; import android.util.Log; +import org.conscrypt.OpenSSLProvider; import org.kde.kdeconnect.Backends.BaseLink; import org.kde.kdeconnect.Backends.BaseLinkProvider; import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider; @@ -37,6 +38,7 @@ import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.UserInterface.MainSettingsActivity; +import java.security.Security; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; @@ -197,6 +199,8 @@ public class BackgroundService extends Service { @Override public void onCreate() { super.onCreate(); + + Security.insertProviderAt(new OpenSSLProvider("KDEConnect SSL Provider"), 1); // Register screen on listener IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); diff --git a/src/org/kde/kdeconnect/Device.java b/src/org/kde/kdeconnect/Device.java index 4992ddd6..d240cb2c 100644 --- a/src/org/kde/kdeconnect/Device.java +++ b/src/org/kde/kdeconnect/Device.java @@ -244,7 +244,7 @@ public class Device implements BaseLink.PackageReceiver { // Each link can set whatever they want in pair package NetworkPackage pairPackage = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR); for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { - linkProvider.pairingHandler.requestPairing(this, pairPackage); + linkProvider.getPairingHandler().requestPairing(this, pairPackage); } pairPackage.set("pair", true); @@ -296,7 +296,7 @@ public class Device implements BaseLink.PackageReceiver { NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR); for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { - linkProvider.pairingHandler.unpair(this, np); + linkProvider.getPairingHandler().unpair(this, np); } np.set("pair", false); sendPackage(np); @@ -320,7 +320,7 @@ public class Device implements BaseLink.PackageReceiver { preferences.edit().putBoolean(deviceId,true).apply(); for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { - linkProvider.pairingHandler.pairingDone(this); + linkProvider.getPairingHandler().pairingDone(this); } reloadPluginsFromSettings(); @@ -337,7 +337,7 @@ public class Device implements BaseLink.PackageReceiver { final NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR); for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { - linkProvider.pairingHandler.accept_pairing(this, np); + linkProvider.getPairingHandler().acceptPairing(this, np); } np.set("pair", true); @@ -369,7 +369,7 @@ public class Device implements BaseLink.PackageReceiver { NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR); for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { - linkProvider.pairingHandler.rejectPairing(this, np); + linkProvider.getPairingHandler().rejectPairing(this, np); } np.set("pair", false); sendPackage(np); @@ -414,7 +414,7 @@ public class Device implements BaseLink.PackageReceiver { byte[] certificateBytes = Base64.decode(certificateString, 0); X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes); certificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(certificateHolder); - Log.e("KDE/Device", "Got certificate "); + Log.i("KDE/Device", "Got certificate "); } catch (Exception e) { e.printStackTrace(); Log.e("KDE/Device", "Error getting certificate"); @@ -495,7 +495,7 @@ public class Device implements BaseLink.PackageReceiver { //Retrieve their public key for (BaseLinkProvider linkProvider : ((BackgroundService)context).getLinkProviders()) { try { - linkProvider.pairingHandler.packageReceived(this, np); + linkProvider.getPairingHandler().packageReceived(this, np); } catch (Exception e) { for (Device.PairingCallback cb : pairingCallback) { cb.pairingFailed(context.getString(R.string.error_invalid_key)); diff --git a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java index 6304e1a3..2eb59aca 100644 --- a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java @@ -42,6 +42,7 @@ import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; +import java.security.Security; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Formatter; @@ -62,6 +63,8 @@ public class SslHelper { public static X509Certificate certificate; //my device's certificate + public static final BouncyCastleProvider BC = new BouncyCastleProvider(); + public static void initialiseCertificate(Context context){ PrivateKey privateKey; PublicKey publicKey; @@ -77,8 +80,6 @@ public class SslHelper { if (!settings.contains("certificate")) { try { - BouncyCastleProvider BC = new BouncyCastleProvider(); - X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE); nameBuilder.addRDN(BCStyle.CN, settings.getString("device_name_preference", "")); // TODO : Chamge it to deviceId nameBuilder.addRDN(BCStyle.OU, "KDE Connect"); @@ -111,7 +112,7 @@ public class SslHelper { SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context); byte[] certificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0); X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes); - certificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(certificateHolder); + certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder); } catch (Exception e) { Log.e("KDE/SslHelper", "Exception reading own certificate"); e.printStackTrace(); @@ -130,13 +131,13 @@ public class SslHelper { SharedPreferences devicePreferences = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE); byte[] certificateBytes = Base64.decode(devicePreferences.getString("certificate", ""), 0); X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes); - remoteDeviceCertificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(certificateHolder); + remoteDeviceCertificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder); } // Setup keystore KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); - keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{certificate});; + keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{certificate}); // Set certificate if device trusted if (remoteDeviceCertificate != null){ keyStore.setCertificateEntry("remoteCertificate", remoteDeviceCertificate); @@ -168,7 +169,7 @@ public class SslHelper { } }; - SSLContext tlsContext = SSLContext.getInstance("TLS"); + SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); if (isDeviceTrusted) { tlsContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); }else {