summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Hudson <nick.hudson@isode.com>2012-01-18 14:22:56 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-02-13 15:12:46 (GMT)
commit9d6f73f13b981fb9430765b171d7b419cbe632cc (patch)
tree5bfdbdfeaa9dc3dc3ff87e92be2612f7aebb03b3 /src/com/isode/stroke/network/JavaConnection.java
parent12740e2b70c48e478af53de31624c388e1e89e0f (diff)
downloadstroke-9d6f73f13b981fb9430765b171d7b419cbe632cc.zip
stroke-9d6f73f13b981fb9430765b171d7b419cbe632cc.tar.bz2
Initial implementation of TLS support
Note that TLS won't be enabled with this patch unless you uncomment the change in PlatformTLSFactories. With that comment removed, then a new CoreClient session will attempt to negotiate TLS if the server supports it. Further changes are required to support this properly, as there appears not to be comprehensive support in the CoreClient class for dealing with situations when the server's certificate is not acceptable. There's also no support yet for setting up client certificates. Further changes will also be needed (see below) to support full parsing of subjectAltNames from server certificates. Significant changes are as follows - TLSProceed - FIXME comments removed - JavaConnection - changed so that it reads bytes from the socket's InputStream, rather than reading chars and then constructing a String out of them from which a byte array is then extracted. While this seemed to work for non-binary data (e.g. non-encrypted XMPP sessions), it breaks when you start sending binary (i.e. TLS) data. - JavaTLSConnectionFactory - implemented - PlatformTLSFactories - By having this return a JSSEContextFactory, then this will cause the client to try TLS if possible. But because other changes are needed to make this work properly, the current code still returns null. - JSSEContext - new class which uses an SSLEngine to handle TLS handshake and subsequent encryption/decryption. This is the main substance of the SSL implementation Note the "hack" in here to cope with SSLEngine requiring that some data be sent from the application before it will do a TLS handshake - JSSEContextFactory - just creates JSSEContexts - JavaCertificate - this wraps an X509Certificate and does *some* of the parsing of a certificate to look for stuff that is expected when verifying an XMPP server certificate (RFC 6120 and RFC 6125). Note that the JDK classes for parsing certificates don't provide an easy way to decode "OTHER" subjectAltNames, and so this implementation does not find XMPP or SRV subjectaltnames from the server certificate. This will need extra work. - JavaTrustManager - obtains the server certificate from the TLS handshake and verifies it. Currently the only verification done is to check that it's in date. More work will be needed to perform proper validation - Where necessary, Remko's copyright comments were changed from GNU to "All rights reserved". Isode copyright notices updated to "2012" Test-information: Set up XMPP server with its own certificate, and checked that TLS gets negotiated and starts OK (provided the server cert contains e.g. a DNS subjectAltName matching its own name). Subsequent operation appears to be as expected.
Diffstat (limited to 'src/com/isode/stroke/network/JavaConnection.java')
-rw-r--r--src/com/isode/stroke/network/JavaConnection.java37
1 files changed, 17 insertions, 20 deletions
diff --git a/src/com/isode/stroke/network/JavaConnection.java b/src/com/isode/stroke/network/JavaConnection.java
index d014f5d..9a3b5da 100644
--- a/src/com/isode/stroke/network/JavaConnection.java
+++ b/src/com/isode/stroke/network/JavaConnection.java
@@ -1,7 +1,6 @@
/*
* Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * All rights reserved.
*/
/*
* Copyright (c) 2010-2012, Isode Limited, London, England.
@@ -9,23 +8,18 @@
*/
package com.isode.stroke.network;
-import com.isode.stroke.base.ByteArray;
-import com.isode.stroke.eventloop.Event.Callback;
-import com.isode.stroke.eventloop.EventLoop;
-import com.isode.stroke.eventloop.EventOwner;
-import java.io.BufferedReader;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+
+import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.eventloop.Event.Callback;
+import com.isode.stroke.eventloop.EventLoop;
+import com.isode.stroke.eventloop.EventOwner;
public class JavaConnection extends Connection implements EventOwner {
@@ -33,7 +27,7 @@ public class JavaConnection extends Connection implements EventOwner {
private final HostAddressPort address_;
private OutputStream write_;
- private BufferedReader read_;
+ private InputStream read_;
private final List<ByteArray> writeBuffer_ = Collections.synchronizedList(new ArrayList<ByteArray>());
public Worker(HostAddressPort address) {
@@ -44,7 +38,7 @@ public class JavaConnection extends Connection implements EventOwner {
try {
socket_ = new Socket(address_.getAddress().getInetAddress(), address_.getPort());
write_ = socket_.getOutputStream();
- read_ = new BufferedReader(new InputStreamReader(socket_.getInputStream(), "utf-8"));
+ read_ = socket_.getInputStream();
} catch (IOException ex) {
handleConnected(true);
return;
@@ -75,11 +69,13 @@ public class JavaConnection extends Connection implements EventOwner {
}
ByteArray data = new ByteArray();
try {
- while (read_.ready()) {
- char[] c = new char[1024];
- int i = read_.read(c, 0, c.length);
+ while (read_.available() != 0) {
+ byte[] b = new byte[1024];
+ int i = read_.read(b,0,b.length);
if (i > 0) {
- data.append(new String(c, 0, i));
+ for (int j=0; j<i; j++) {
+ data.append(b[j]);
+ }
}
}
} catch (IOException ex) {
@@ -107,7 +103,7 @@ public class JavaConnection extends Connection implements EventOwner {
private void handleConnected(final boolean error) {
eventLoop_.postEvent(new Callback() {
public void run() {
- onConnectFinished.emit(error);
+ onConnectFinished.emit(Boolean.valueOf(error));
}
});
}
@@ -182,4 +178,5 @@ public class JavaConnection extends Connection implements EventOwner {
private boolean disconnecting_ = false;
private Socket socket_;
private Worker worker_;
+
}