mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-31 22:25:08 +00:00
Added support to verify keys during pair
This commit is contained in:
@@ -25,6 +25,39 @@
|
|||||||
android:layout_gravity="left|center_vertical"
|
android:layout_gravity="left|center_vertical"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/secret_keys"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/my_device_key"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/pairing_accept"
|
||||||
|
android:layout_weight="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/remote_device_key"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/pairing_reject"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/security_message"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/pair_button"
|
android:id="@+id/pair_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@@ -61,6 +61,9 @@
|
|||||||
<string name="error_canceled_by_user">Canceled by user</string>
|
<string name="error_canceled_by_user">Canceled by user</string>
|
||||||
<string name="error_canceled_by_other_peer">Canceled by other peer</string>
|
<string name="error_canceled_by_other_peer">Canceled by other peer</string>
|
||||||
<string name="error_invalid_key">Invalid key received</string>
|
<string name="error_invalid_key">Invalid key received</string>
|
||||||
|
<string name="my_device_key">My device key : </string>
|
||||||
|
<string name="remote_device_key">Remote device key : </string>
|
||||||
|
<string name="security_message">Be sure to match these keys before pairing for security purposes</string>
|
||||||
<string name="pair_requested">Pair requested</string>
|
<string name="pair_requested">Pair requested</string>
|
||||||
<string name="pairing_request_from">Pairing request from %1s</string>
|
<string name="pairing_request_from">Pairing request from %1s</string>
|
||||||
<string name="received_url_title">Received link from %1s</string>
|
<string name="received_url_title">Received link from %1s</string>
|
||||||
|
@@ -26,6 +26,7 @@ import org.json.JSONObject;
|
|||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||||
import org.kde.kdeconnect.NetworkPackage;
|
import org.kde.kdeconnect.NetworkPackage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -88,7 +89,7 @@ public class LanLink extends BaseLink {
|
|||||||
|
|
||||||
//Encrypt if key provided
|
//Encrypt if key provided
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
np = np.encrypt(key);
|
np = RsaHelper.encrypt(np, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Send body of the network package
|
//Send body of the network package
|
||||||
@@ -169,7 +170,7 @@ public class LanLink extends BaseLink {
|
|||||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
|
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
np = np.decrypt(privateKey);
|
np = RsaHelper.decrypt(np, privateKey);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Log.e("KDE/onPackageReceived","Exception reading the key needed to decrypt the package");
|
Log.e("KDE/onPackageReceived","Exception reading the key needed to decrypt the package");
|
||||||
|
@@ -40,7 +40,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.security.auth.login.LoginException;
|
|
||||||
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
@@ -48,13 +47,11 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.nio.NioEventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.DatagramPacket;
|
import io.netty.channel.socket.DatagramPacket;
|
||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
@@ -86,8 +83,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
private class TcpHandler extends SimpleChannelInboundHandler{
|
private class TcpHandler extends SimpleChannelInboundHandler{
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
super.exceptionCaught(ctx, cause);
|
|
||||||
cause.printStackTrace();
|
cause.printStackTrace();
|
||||||
|
// TODO : Add necessary action on ssl handshake failure
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -181,8 +178,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
Certificate certificate = sslEngine.getSession().getPeerCertificates()[0];
|
Certificate certificate = sslEngine.getSession().getPeerCertificates()[0];
|
||||||
np.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
np.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||||
|
link.setOnSsl(true);
|
||||||
}
|
}
|
||||||
link.setOnSsl(true);
|
|
||||||
addLink(np, link);
|
addLink(np, link);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -191,7 +188,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
addLink(np, link);
|
addLink(np, link); // If error in ssl engine, which is returning null in some cases
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -285,11 +282,11 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
try {
|
try {
|
||||||
Certificate certificate = sslHandler.engine().getSession().getPeerCertificates()[0];
|
Certificate certificate = sslHandler.engine().getSession().getPeerCertificates()[0];
|
||||||
identityPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
identityPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||||
|
link.setOnSsl(true);
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
link.setOnSsl(true);
|
|
||||||
addLink(identityPackage, link);
|
addLink(identityPackage, link);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -450,13 +447,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
|
|
||||||
//FilesHelper.LogOpenFileCount();
|
//FilesHelper.LogOpenFileCount();
|
||||||
|
|
||||||
//Keep existing connections open while unbinding the socket
|
|
||||||
// tcpAcceptor.setCloseOnDeactivation(false);
|
|
||||||
// onStop();
|
|
||||||
// tcpAcceptor.setCloseOnDeactivation(true);
|
|
||||||
|
|
||||||
//FilesHelper.LogOpenFileCount();
|
|
||||||
|
|
||||||
onStart();
|
onStart();
|
||||||
|
|
||||||
//FilesHelper.LogOpenFileCount();
|
//FilesHelper.LogOpenFileCount();
|
||||||
|
@@ -23,6 +23,7 @@ package org.kde.kdeconnect.Backends.LoopbackBackend;
|
|||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||||
import org.kde.kdeconnect.NetworkPackage;
|
import org.kde.kdeconnect.NetworkPackage;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
@@ -42,12 +43,12 @@ public class LoopbackLink extends BaseLink {
|
|||||||
public void sendPackageEncrypted(NetworkPackage in, Device.SendPackageStatusCallback callback, PublicKey key) {
|
public void sendPackageEncrypted(NetworkPackage in, Device.SendPackageStatusCallback callback, PublicKey key) {
|
||||||
try {
|
try {
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
in = in.encrypt(key);
|
in = RsaHelper.encrypt(in, key);
|
||||||
}
|
}
|
||||||
String s = in.serialize();
|
String s = in.serialize();
|
||||||
NetworkPackage out= NetworkPackage.unserialize(s);
|
NetworkPackage out= NetworkPackage.unserialize(s);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
out = out.decrypt(privateKey);
|
out = RsaHelper.decrypt(out, privateKey);
|
||||||
}
|
}
|
||||||
packageReceived(out);
|
packageReceived(out);
|
||||||
if (in.hasPayload()) {
|
if (in.hasPayload()) {
|
||||||
|
@@ -62,6 +62,8 @@ public class SslHelper {
|
|||||||
Server
|
Server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static X509Certificate certificate; //my device's certificate
|
||||||
|
|
||||||
public static void initialiseCertificate(Context context){
|
public static void initialiseCertificate(Context context){
|
||||||
PrivateKey privateKey;
|
PrivateKey privateKey;
|
||||||
PublicKey publicKey;
|
PublicKey publicKey;
|
||||||
@@ -94,7 +96,7 @@ public class SslHelper {
|
|||||||
publicKey
|
publicKey
|
||||||
);
|
);
|
||||||
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privateKey);
|
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privateKey);
|
||||||
X509Certificate certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
|
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
|
||||||
|
|
||||||
SharedPreferences.Editor edit = settings.edit();
|
SharedPreferences.Editor edit = settings.edit();
|
||||||
edit.putString("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
edit.putString("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||||
@@ -106,6 +108,16 @@ public class SslHelper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("KDE/SslHelper", "Exception reading own certificate");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,12 +131,6 @@ public class SslHelper {
|
|||||||
// Get device private key
|
// Get device private key
|
||||||
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
||||||
|
|
||||||
// Get my certificate
|
|
||||||
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
byte[] myCertificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
|
|
||||||
X509CertificateHolder myCertificateHolder = new X509CertificateHolder(myCertificateBytes);
|
|
||||||
X509Certificate myCertificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(myCertificateHolder);
|
|
||||||
|
|
||||||
// Get remote device certificate if trusted
|
// Get remote device certificate if trusted
|
||||||
java.security.cert.Certificate remoteDeviceCertificate = null;
|
java.security.cert.Certificate remoteDeviceCertificate = null;
|
||||||
if (isDeviceTrusted){
|
if (isDeviceTrusted){
|
||||||
@@ -137,7 +143,7 @@ public class SslHelper {
|
|||||||
// Setup keystore
|
// Setup keystore
|
||||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
keyStore.load(null, null);
|
keyStore.load(null, null);
|
||||||
keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{myCertificate});;
|
keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{certificate});;
|
||||||
// Set certificate if device trusted
|
// Set certificate if device trusted
|
||||||
if (remoteDeviceCertificate != null){
|
if (remoteDeviceCertificate != null){
|
||||||
keyStore.setCertificateEntry("remoteCertificate", remoteDeviceCertificate);
|
keyStore.setCertificateEntry("remoteCertificate", remoteDeviceCertificate);
|
||||||
|
@@ -193,56 +193,6 @@ public class NetworkPackage {
|
|||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkPackage encrypt(PublicKey publicKey) throws GeneralSecurityException {
|
|
||||||
|
|
||||||
String serialized = 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("NetworkPackage", "Encrypted " + chunks.length()+" chunks");
|
|
||||||
|
|
||||||
NetworkPackage encrypted = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_ENCRYPTED);
|
|
||||||
encrypted.set("data", chunks);
|
|
||||||
encrypted.setPayload(mPayload, mPayloadSize);
|
|
||||||
return encrypted;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkPackage decrypt(PrivateKey privateKey) throws GeneralSecurityException, JSONException {
|
|
||||||
|
|
||||||
JSONArray chunks = mBody.getJSONArray("data");
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
|
|
||||||
String decryptedJson = "";
|
|
||||||
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 += decryptedChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkPackage decrypted = unserialize(decryptedJson);
|
|
||||||
decrypted.setPayload(mPayload, mPayloadSize);
|
|
||||||
return decrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public NetworkPackage createIdentityPackage(Context context) {
|
static public NetworkPackage createIdentityPackage(Context context) {
|
||||||
|
|
||||||
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_IDENTITY);
|
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_IDENTITY);
|
||||||
|
@@ -25,14 +25,21 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.kde.kdeconnect.BackgroundService;
|
import org.kde.kdeconnect.BackgroundService;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
||||||
import org.kde.kdeconnect_tp.R;
|
import org.kde.kdeconnect_tp.R;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.Formatter;
|
||||||
|
|
||||||
public class PairActivity extends ActionBarActivity {
|
public class PairActivity extends ActionBarActivity {
|
||||||
|
|
||||||
private String deviceId;
|
private String deviceId;
|
||||||
@@ -48,6 +55,7 @@ public class PairActivity extends ActionBarActivity {
|
|||||||
((TextView) findViewById(R.id.pair_message)).setText(R.string.pair_requested);
|
((TextView) findViewById(R.id.pair_message)).setText(R.string.pair_requested);
|
||||||
findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
||||||
findViewById(R.id.pair_button).setVisibility(View.GONE);
|
findViewById(R.id.pair_button).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.secret_keys).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.pair_request).setVisibility(View.VISIBLE);
|
findViewById(R.id.pair_request).setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -67,6 +75,7 @@ public class PairActivity extends ActionBarActivity {
|
|||||||
public void run() {
|
public void run() {
|
||||||
((TextView) findViewById(R.id.pair_message)).setText(error);
|
((TextView) findViewById(R.id.pair_message)).setText(error);
|
||||||
findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.secret_keys).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.pair_button).setVisibility(View.VISIBLE);
|
findViewById(R.id.pair_button).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.pair_request).setVisibility(View.GONE);
|
findViewById(R.id.pair_request).setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
@@ -104,12 +113,39 @@ public class PairActivity extends ActionBarActivity {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show secret keys based on certificate if device are connected using ssl
|
||||||
|
BackgroundService.RunCommand(PairActivity.this, new BackgroundService.InstanceCallback() {
|
||||||
|
@Override
|
||||||
|
public void onServiceStart(BackgroundService service) {
|
||||||
|
device = service.getDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
Log.e("KDE/PairActivity", "Device is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device.certificate == null) {
|
||||||
|
Log.e("KDE/PairActivity", "Device certificate is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
((TextView) findViewById(R.id.remote_device_key)).setText(getApplicationContext().getResources().getString(R.string.remote_device_key) + byteArray2Hex(MessageDigest.getInstance("SHA-1").digest(device.certificate.getEncoded())).toUpperCase());
|
||||||
|
((TextView) findViewById(R.id.my_device_key)).setText(getApplicationContext().getResources().getString(R.string.my_device_key) + byteArray2Hex(MessageDigest.getInstance("SHA-1").digest(SslHelper.certificate.getEncoded())).toUpperCase());
|
||||||
|
findViewById(R.id.secret_keys).setVisibility(View.VISIBLE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
final Button pairButton = (Button)findViewById(R.id.pair_button);
|
final Button pairButton = (Button)findViewById(R.id.pair_button);
|
||||||
pairButton.setOnClickListener(new View.OnClickListener() {
|
pairButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
pairButton.setVisibility(View.GONE);
|
pairButton.setVisibility(View.GONE);
|
||||||
((TextView) findViewById(R.id.pair_message)).setText("");
|
((TextView) findViewById(R.id.pair_message)).setText("");
|
||||||
|
findViewById(R.id.secret_keys).setVisibility(View.GONE);
|
||||||
findViewById(R.id.pair_progress).setVisibility(View.VISIBLE);
|
findViewById(R.id.pair_progress).setVisibility(View.VISIBLE);
|
||||||
BackgroundService.RunCommand(PairActivity.this, new BackgroundService.InstanceCallback() {
|
BackgroundService.RunCommand(PairActivity.this, new BackgroundService.InstanceCallback() {
|
||||||
@Override
|
@Override
|
||||||
@@ -173,4 +209,13 @@ public class PairActivity extends ActionBarActivity {
|
|||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String byteArray2Hex(final byte[] hash) {
|
||||||
|
Formatter formatter = new Formatter();
|
||||||
|
// Using first 4 bytes out of 20, is this secure ?
|
||||||
|
for (int i=0 ; i<4 ; i++) {
|
||||||
|
formatter.format("%02x", hash[i]);
|
||||||
|
}
|
||||||
|
return formatter.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user