2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-29 13:17:43 +00:00

Further simplified lanbackend

This commit is contained in:
Albert Vaca 2016-06-20 14:26:49 +02:00
parent d3ab18b721
commit 4fc6ca8d4f
3 changed files with 98 additions and 138 deletions

View File

@ -21,7 +21,6 @@
package org.kde.kdeconnect.Backends.LanBackend; package org.kde.kdeconnect.Backends.LanBackend;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
import org.json.JSONObject; import org.json.JSONObject;
@ -45,8 +44,6 @@ import java.net.SocketTimeoutException;
import java.nio.channels.NotYetConnectedException; import java.nio.channels.NotYetConnectedException;
import java.security.PublicKey; import java.security.PublicKey;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
public class LanLink extends BaseLink { public class LanLink extends BaseLink {
@ -62,6 +59,10 @@ public class LanLink extends BaseLink {
private Socket socket = null; private Socket socket = null;
interface SocketClosedCallback {
void socketClosed(LanLink brokenLink, boolean linkHasAnotherSocket);
};
@Override @Override
public void disconnect() { public void disconnect() {
@ -81,7 +82,7 @@ public class LanLink extends BaseLink {
} }
//Returns the old socket //Returns the old socket
public Socket reset(final Socket newSocket, ConnectionStarted connectionSource, final LanLinkProvider linkProvider) throws IOException { public Socket reset(final Socket newSocket, ConnectionStarted connectionSource, final SocketClosedCallback callback) throws IOException {
Socket oldSocket = socket; Socket oldSocket = socket;
socket = newSocket; socket = newSocket;
@ -92,8 +93,8 @@ public class LanLink extends BaseLink {
oldSocket.close(); //This should cancel the readThread oldSocket.close(); //This should cancel the readThread
} }
Log.e("LanLink", "Start listening"); //Log.e("LanLink", "Start listening");
//Start listening //Create a thread to take care of incoming data for the new socket
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -107,16 +108,18 @@ public class LanLink extends BaseLink {
continue; continue;
} }
if (packet == null) { if (packet == null) {
throw new IOException("Read null"); throw new IOException("End of stream");
}
if (packet.isEmpty()) {
continue;
} }
if (packet.isEmpty()) continue;
NetworkPackage np = NetworkPackage.unserialize(packet); NetworkPackage np = NetworkPackage.unserialize(packet);
injectNetworkPackage(np); receivedNetworkPackage(np);
} }
} catch (Exception e) { } catch (Exception e) {
Log.e("LanLink", "Socket closed " + newSocket.hashCode() + " reason: " + e.getMessage()); Log.i("LanLink", "Socket closed: " + newSocket.hashCode() + ". Reason: " + e.getMessage());
boolean thereIsaANewSocket = (newSocket != socket); boolean thereIsaANewSocket = (newSocket != socket);
linkProvider.socketClosed(newSocket, thereIsaANewSocket); callback.socketClosed(LanLink.this, thereIsaANewSocket);
} }
} }
}).start(); }).start();
@ -153,7 +156,7 @@ public class LanLink extends BaseLink {
//Prepare socket for the payload //Prepare socket for the payload
final ServerSocket server; final ServerSocket server;
if (np.hasPayload()) { if (np.hasPayload()) {
server = openTcpSocketOnFreePort(context, getDeviceId()); server = LanLinkProvider.openServerSocketOnFreePort(LanLinkProvider.PAYLOAD_TRANSFER_MIN_PORT);
JSONObject payloadTransferInfo = new JSONObject(); JSONObject payloadTransferInfo = new JSONObject();
payloadTransferInfo.put("port", server.getLocalPort()); payloadTransferInfo.put("port", server.getLocalPort());
np.setPayloadTransferInfo(payloadTransferInfo); np.setPayloadTransferInfo(payloadTransferInfo);
@ -182,38 +185,48 @@ public class LanLink extends BaseLink {
//Send payload //Send payload
if (server != null) { if (server != null) {
OutputStream socket = null; Socket payloadSocket = null;
OutputStream outputStream = null;
InputStream inputStream = null;
try { try {
//Wait a maximum of 10 seconds for the other end to establish a connection with our socket, close it afterwards //Wait a maximum of 10 seconds for the other end to establish a connection with our socket, close it afterwards
server.setSoTimeout(10*1000); server.setSoTimeout(10*1000);
socket = server.accept().getOutputStream();
payloadSocket = server.accept();
//Convert to SSL if needed
if (socket instanceof SSLSocket) {
payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, false);
}
outputStream = payloadSocket.getOutputStream();
inputStream = np.getPayload();
Log.i("KDE/LanLink", "Beginning to send payload"); Log.i("KDE/LanLink", "Beginning to send payload");
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int bytesRead; int bytesRead;
long progress = 0; long progress = 0;
InputStream stream = np.getPayload(); while ((bytesRead = inputStream.read(buffer)) != -1) {
while ((bytesRead = stream.read(buffer)) != -1) {
//Log.e("ok",""+bytesRead); //Log.e("ok",""+bytesRead);
progress += bytesRead; progress += bytesRead;
socket.write(buffer, 0, bytesRead); outputStream.write(buffer, 0, bytesRead);
if (np.getPayloadSize() > 0) { if (np.getPayloadSize() > 0) {
callback.sendProgress((int)(progress / np.getPayloadSize())); callback.sendProgress((int)(progress / np.getPayloadSize()));
} }
} }
socket.flush(); outputStream.flush();
stream.close(); outputStream.close();
Log.i("KDE/LanLink", "Finished sending payload ("+progress+" bytes written)"); Log.i("KDE/LanLink", "Finished sending payload ("+progress+" bytes written)");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
Log.e("KDE/sendPackage", "Exception: "+e); Log.e("KDE/sendPackage", "Exception: "+e);
callback.sendFailure(e); callback.sendFailure(e);
return; return;
} finally { } finally {
if (socket != null) {
try { socket.close(); } catch (Exception e) { }
}
try { server.close(); } catch (Exception e) { } try { server.close(); } catch (Exception e) { }
try { payloadSocket.close(); } catch (Exception e) { }
try { inputStream.close(); } catch (Exception e) { }
try { outputStream.close(); } catch (Exception e) { }
} }
} }
@ -244,7 +257,7 @@ public class LanLink extends BaseLink {
sendPackageInternal(np, callback, key); sendPackageInternal(np, callback, key);
} }
public void injectNetworkPackage(NetworkPackage np) { private void receivedNetworkPackage(NetworkPackage np) {
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) { if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
try { try {
@ -257,16 +270,12 @@ public class LanLink extends BaseLink {
if (np.hasPayloadTransferInfo()) { if (np.hasPayloadTransferInfo()) {
Socket payloadSocket = null; Socket payloadSocket = new Socket();
try { try {
// Use ssl if existing link is on ssl // Use ssl if existing link is on ssl
if (socket instanceof SSLSocket) { if (socket instanceof SSLSocket) {
SSLContext sslContext = SslHelper.getSslContext(context, getDeviceId(), true); payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, true);
payloadSocket = sslContext.getSocketFactory().createSocket();
} else {
payloadSocket = new Socket();
} }
int tcpPort = np.getPayloadTransferInfo().getInt("port"); int tcpPort = np.getPayloadTransferInfo().getInt("port");
InetSocketAddress address = (InetSocketAddress) socket.getRemoteSocketAddress(); InetSocketAddress address = (InetSocketAddress) socket.getRemoteSocketAddress();
payloadSocket.connect(new InetSocketAddress(address.getAddress(), tcpPort)); payloadSocket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
@ -282,49 +291,6 @@ public class LanLink extends BaseLink {
packageReceived(np); packageReceived(np);
} }
ServerSocket openTcpSocketOnFreePort(Context context, String deviceId) throws IOException {
if (socket instanceof SSLSocket) {
return openSecureServerSocket(context, deviceId);
} else {
return openUnsecureSocketOnFreePort(1739);
}
}
static ServerSocket openUnsecureSocketOnFreePort(int minPort) throws IOException {
int tcpPort = minPort;
while(tcpPort < 1764) {
try {
ServerSocket candidateServer = new ServerSocket();
candidateServer.bind(new InetSocketAddress(tcpPort));
Log.i("KDE/LanLink", "Using port "+tcpPort);
return candidateServer;
} catch(IOException e) {
tcpPort++;
}
}
Log.e("KDE/LanLink", "No more ports available");
throw new IOException("No more ports available");
}
static ServerSocket openSecureServerSocket(Context context, String deviceId) throws IOException{
SSLContext tlsContext = SslHelper.getSslContext(context, deviceId, true);
SSLServerSocketFactory sslServerSocketFactory = tlsContext.getServerSocketFactory();
int tcpPort = 1739;
while(tcpPort < 1764) {
try {
ServerSocket candidateServer = sslServerSocketFactory.createServerSocket();
candidateServer.bind(new InetSocketAddress(tcpPort));
Log.i("KDE/LanLink", "Using port "+tcpPort);
return candidateServer;
} catch(IOException e) {
tcpPort++;
}
}
Log.e("KDE/LanLink", "No more ports available");
throw new IOException("No more ports available");
}
@Override @Override
public boolean linkShouldBeKeptAlive() { public boolean linkShouldBeKeptAlive() {

View File

@ -43,6 +43,7 @@ import java.io.OutputStream;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
@ -56,22 +57,20 @@ import javax.net.SocketFactory;
import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class LanLinkProvider extends BaseLinkProvider { public class LanLinkProvider extends BaseLinkProvider implements LanLink.SocketClosedCallback {
public static final int MIN_VERSION_WITH_SSL_SUPPORT = 6; public static final int MIN_VERSION_WITH_SSL_SUPPORT = 6;
public static final int MIN_VERSION_WITH_NEW_PORT_SUPPORT = 7; public static final int MIN_VERSION_WITH_NEW_PORT_SUPPORT = 7;
public static final String KEY_CUSTOM_DEVLIST_PREFERENCE = "device_list_preference"; final static int MIN_PORT_LEGACY = 1714;
final static int MIN_PORT = 1716;
private final static int oldPort = 1714; final static int MAX_PORT = 1764;
private final static int port = 1716; final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
private final Context context; private final Context context;
private final HashMap<String, LanLink> visibleComputers = new HashMap<>(); //Links by device id private final HashMap<String, LanLink> visibleComputers = new HashMap<>(); //Links by device id
private final HashMap<Socket, LanLink> nioLinks = new HashMap<>(); //Links by socket
private ServerSocket tcpServer; private ServerSocket tcpServer;
private DatagramSocket udpServer; private DatagramSocket udpServer;
@ -82,26 +81,12 @@ public class LanLinkProvider extends BaseLinkProvider {
// To prevent infinte loop between Android < IceCream because both device can only broadcast identity package but cannot connect via TCP // To prevent infinte loop between Android < IceCream because both device can only broadcast identity package but cannot connect via TCP
private ArrayList<InetAddress> reverseConnectionBlackList = new ArrayList<>(); private ArrayList<InetAddress> reverseConnectionBlackList = new ArrayList<>();
public void socketClosed(Socket socket, boolean linkHasAnotherSocket) { @Override // SocketClosedCallback
final LanLink brokenLink = nioLinks.remove(socket); public void socketClosed(final LanLink brokenLink, boolean linkHasAnotherSocket) {
if (brokenLink != null) { if (!linkHasAnotherSocket) {
String deviceId = brokenLink.getDeviceId();
if (!linkHasAnotherSocket) { visibleComputers.remove(deviceId);
String deviceId = brokenLink.getDeviceId(); connectionLost(brokenLink);
visibleComputers.remove(deviceId);
new Thread(new Runnable() {
@Override
public void run() {
//Wait a bit before emitting connectionLost, in case the same device re-appears
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
connectionLost(brokenLink);
}
}).start();
}
} }
} }
@ -113,26 +98,22 @@ public class LanLinkProvider extends BaseLinkProvider {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = reader.readLine(); String message = reader.readLine();
networkPackage = NetworkPackage.unserialize(message); networkPackage = NetworkPackage.unserialize(message);
//Log.i("TcpListener","Received TCP package: "+networkPackage.serialize()); //Log.e("TcpListener","Received TCP package: "+networkPackage.serialize());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return; return;
} }
if (networkPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) { if (!networkPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
Log.i("KDE/LanLinkProvider", "Identity package received from a TCP connection from " + networkPackage.getString("deviceName")); Log.e("KDE/LanLinkProvider", "Expecting an identity package instead of " + networkPackage.getType());
identityPackageReceived(networkPackage, socket, LanLink.ConnectionStarted.Locally); return;
} else {
LanLink link = nioLinks.get(socket);
if (link== null) {
Log.e("KDE/LanLinkProvider","Expecting an identity package instead of " + networkPackage.getType());
} else {
link.injectNetworkPackage(networkPackage);
}
} }
Log.i("KDE/LanLinkProvider", "Identity package received from a TCP connection from " + networkPackage.getString("deviceName"));
identityPackageReceived(networkPackage, socket, LanLink.ConnectionStarted.Locally);
} }
//I've received their broadcast and should connect to their TCP socket and send my identity.
protected void udpPacketReceived(DatagramPacket packet) throws Exception { protected void udpPacketReceived(DatagramPacket packet) throws Exception {
final InetAddress address = packet.getAddress(); final InetAddress address = packet.getAddress();
@ -153,21 +134,22 @@ public class LanLinkProvider extends BaseLinkProvider {
} }
} }
if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPackage.getInt("tcpPort") < port) { if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPackage.getInt("tcpPort") < MIN_PORT) {
Log.w("KDE/LanLinkProvider", "Ignoring a udp broadcast from an old port because it comes from a device which knows about the new 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; return;
} }
Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPackage.getString("deviceName")); Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPackage.getString("deviceName"));
int tcpPort = identityPackage.getInt("tcpPort", port); int tcpPort = identityPackage.getInt("tcpPort", MIN_PORT);
SocketFactory socketFactory = SocketFactory.getDefault(); SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket(address, tcpPort); Socket socket = socketFactory.createSocket(address, tcpPort);
configureSocket(socket); configureSocket(socket);
OutputStream out = socket.getOutputStream(); OutputStream out = socket.getOutputStream();
out.write(NetworkPackage.createIdentityPackage(context).serialize().getBytes()); NetworkPackage myIdentity = NetworkPackage.createIdentityPackage(context);
out.write(myIdentity.serialize().getBytes());
out.flush(); out.flush();
identityPackageReceived(identityPackage, socket, LanLink.ConnectionStarted.Remotely); identityPackageReceived(identityPackage, socket, LanLink.ConnectionStarted.Remotely);
@ -188,7 +170,6 @@ public class LanLinkProvider extends BaseLinkProvider {
// Try to cause a reverse connection // Try to cause a reverse connection
onNetworkChange(); onNetworkChange();
} }
} }
} }
@ -217,14 +198,11 @@ public class LanLinkProvider extends BaseLinkProvider {
if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) { if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) {
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE); SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
final boolean isDeviceTrusted = preferences.getBoolean(deviceId, false); boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
Log.i("KDE/LanLinkProvider","Starting SSL handshake with " + identityPackage.getString("deviceName") + " trusted:"+isDeviceTrusted); Log.i("KDE/LanLinkProvider","Starting SSL handshake with " + identityPackage.getString("deviceName") + " trusted:"+isDeviceTrusted);
SSLSocketFactory sslsocketFactory = SslHelper.getSslContext(context, deviceId, isDeviceTrusted).getSocketFactory(); final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
final SSLSocket sslsocket = (SSLSocket)sslsocketFactory.createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true);
SslHelper.configureSslSocket(sslsocket, isDeviceTrusted, clientMode);
configureSocket(sslsocket);
sslsocket.addHandshakeCompletedListener(new HandshakeCompletedListener() { sslsocket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
@Override @Override
public void handshakeCompleted(HandshakeCompletedEvent event) { public void handshakeCompleted(HandshakeCompletedEvent event) {
@ -276,19 +254,10 @@ public class LanLinkProvider extends BaseLinkProvider {
//Update old link //Update old link
Log.i("KDE/LanLinkProvider", "Reusing same link for device " + deviceId); Log.i("KDE/LanLinkProvider", "Reusing same link for device " + deviceId);
final Socket oldSocket = currentLink.reset(socket, connectionOrigin, this); final Socket oldSocket = currentLink.reset(socket, connectionOrigin, this);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
nioLinks.remove(oldSocket);
//Log.e("KDE/LanLinkProvider", "Forgetting about socket " + socket.hashCode());
}
}, 500); //Stop accepting messages from the old socket after 500ms
nioLinks.put(socket, currentLink);
//Log.e("KDE/LanLinkProvider", "Replacing socket. old: "+ oldSocket.hashCode() + " - new: "+ socket.hashCode()); //Log.e("KDE/LanLinkProvider", "Replacing socket. old: "+ oldSocket.hashCode() + " - new: "+ socket.hashCode());
} else { } else {
//Let's create the link //Let's create the link
LanLink link = new LanLink(context, deviceId, this, socket, connectionOrigin); LanLink link = new LanLink(context, deviceId, this, socket, connectionOrigin);
nioLinks.put(socket, link);
visibleComputers.put(deviceId, link); visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link); connectionAccepted(identityPackage, link);
} }
@ -333,7 +302,7 @@ public class LanLinkProvider extends BaseLinkProvider {
private void setupTcpListener() { private void setupTcpListener() {
try { try {
tcpServer = LanLink.openUnsecureSocketOnFreePort(port); tcpServer = openServerSocketOnFreePort(MIN_PORT);
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -356,13 +325,29 @@ public class LanLinkProvider extends BaseLinkProvider {
} }
} }
static ServerSocket openServerSocketOnFreePort(int minPort) throws IOException {
int tcpPort = minPort;
while(tcpPort < MAX_PORT) {
try {
ServerSocket candidateServer = new ServerSocket();
candidateServer.bind(new InetSocketAddress(tcpPort));
Log.i("KDE/LanLink", "Using port "+tcpPort);
return candidateServer;
} catch(IOException e) {
tcpPort++;
}
}
Log.e("KDE/LanLink", "No ports available");
throw new IOException("No ports available");
}
void broadcastUdpPackage() { void broadcastUdpPackage() {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_CUSTOM_DEVLIST_PREFERENCE, ""); String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(CustomDevicesActivity.KEY_CUSTOM_DEVLIST_PREFERENCE, "");
ArrayList<String> iplist = new ArrayList<>(); ArrayList<String> iplist = new ArrayList<>();
if (!deviceListPrefs.isEmpty()) { if (!deviceListPrefs.isEmpty()) {
iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs); iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs);
@ -370,7 +355,7 @@ public class LanLinkProvider extends BaseLinkProvider {
iplist.add("255.255.255.255"); //Default: broadcast. iplist.add("255.255.255.255"); //Default: broadcast.
NetworkPackage identity = NetworkPackage.createIdentityPackage(context); NetworkPackage identity = NetworkPackage.createIdentityPackage(context);
identity.set("tcpPort", port); identity.set("tcpPort", MIN_PORT);
DatagramSocket socket = null; DatagramSocket socket = null;
byte[] bytes = null; byte[] bytes = null;
try { try {
@ -388,8 +373,8 @@ public class LanLinkProvider extends BaseLinkProvider {
for (String ipstr : iplist) { for (String ipstr : iplist) {
try { try {
InetAddress client = InetAddress.getByName(ipstr); InetAddress client = InetAddress.getByName(ipstr);
socket.send(new DatagramPacket(bytes, bytes.length, client, port)); socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT));
socket.send(new DatagramPacket(bytes, bytes.length, client, oldPort)); socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT_LEGACY));
//Log.i("KDE/LanLinkProvider","Udp identity package sent to address "+client); //Log.i("KDE/LanLinkProvider","Udp identity package sent to address "+client);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -412,8 +397,8 @@ public class LanLinkProvider extends BaseLinkProvider {
listening = true; listening = true;
udpServer = setupUdpListener(port); udpServer = setupUdpListener(MIN_PORT);
udpServerOldPort = setupUdpListener(oldPort); udpServerOldPort = setupUdpListener(MIN_PORT_LEGACY);
// Due to certificate request from SSL server to client, the certificate request message from device with latest android version to device with // Due to certificate request from SSL server to client, the certificate request message from device with latest android version to device with
// old android version causes a FATAL ALERT message stating that incorrect certificate request // old android version causes a FATAL ALERT message stating that incorrect certificate request

View File

@ -41,6 +41,7 @@ import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel; import java.nio.channels.ServerSocketChannel;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.MessageDigest; import java.security.MessageDigest;
@ -58,6 +59,7 @@ import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
@ -132,6 +134,7 @@ public class SslHelper {
} }
public static SSLContext getSslContext(Context context, String deviceId, boolean isDeviceTrusted) { public static SSLContext getSslContext(Context context, String deviceId, boolean isDeviceTrusted) {
//TODO: Cache
try { try {
// Get device private key // Get device private key
PrivateKey privateKey = RsaHelper.getPrivateKey(context); PrivateKey privateKey = RsaHelper.getPrivateKey(context);
@ -225,6 +228,13 @@ public class SslHelper {
} }
public static SSLSocket convertToSslSocket(Context context, Socket socket, String deviceId, boolean isDeviceTrusted, boolean clientMode) throws IOException {
SSLSocketFactory sslsocketFactory = SslHelper.getSslContext(context, deviceId, isDeviceTrusted).getSocketFactory();
SSLSocket sslsocket = (SSLSocket)sslsocketFactory.createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true);
SslHelper.configureSslSocket(sslsocket, isDeviceTrusted, clientMode);
return sslsocket;
}
public static String getCertificateHash(Certificate certificate) { public static String getCertificateHash(Certificate certificate) {
try { try {
byte[] hash = MessageDigest.getInstance("SHA-1").digest(certificate.getEncoded()); byte[] hash = MessageDigest.getInstance("SHA-1").digest(certificate.getEncoded());
@ -238,7 +248,6 @@ public class SslHelper {
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
public static Certificate parseCertificate(byte[] certificateBytes) throws IOException, CertificateException { public static Certificate parseCertificate(byte[] certificateBytes) throws IOException, CertificateException {