Problems setting up a secure websocket server / connection

1,138 views
Skip to first unread message

Steven Hickerson

unread,
Dec 24, 2013, 12:00:03 AM12/24/13
to ve...@googlegroups.com
I'm really hoping someone can help me here.  I'm trying to set up a secure websocket connection and cannot for the life of me to get it to work.  It just always immediately rejects the connection and I have no idea why.

This is the code I'm using server side atm:

package websockets;


import org.vertx.java.core.Handler;
import org.vertx.java.core.buffer.Buffer;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.core.http.ServerWebSocket;
import org.vertx.java.platform.Verticle;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.core.json.JsonArray;

public class PF_Character_Server extends Verticle {
        public void start() {
                vertx.createHttpServer().setSSL(true).setKeyStorePath("keystore.jks").setKeyStorePassword("mypass").websocketHandler(new Handler<ServerWebSocket>() {
                        public void handle(final ServerWebSocket ws) {
                                //if (ws.path().equals("/pfcharacter")) {
                                        ws.dataHandler(new Handler<Buffer>() {
                                                public void handle(Buffer data) {
                                                        JsonObject msg = new JsonObject(data.toString());
                                                        switch (msg.getString("type")) {
                                                                case "login":
                                                                        ws.writeTextFrame("SUCCESS");
                                                                        break;
                                                                case "character_info":
                                                                        break;
                                                                case "msg":
                                                                        ws.writeTextFrame(msg.getString("msg"));
                                                                        break;
                                                                default:

                                                        }
                                                }
                                        });
                                /*} else {
                                        ws.reject();
                                }*/
                        }
                }).requestHandler(new Handler<HttpServerRequest>() {
                        public void handle(HttpServerRequest req) {
                                if (req.path().equals("/")) req.response().sendFile("index.html"); // Serve the html
                        }
                }).listen(8124);
        }
}


You can see I've commented out the path check because I've been trying to eliminate what could be the problem.  The keystore is one that I created using:
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass mypass -validity 360 -keysize 2048

And I did create it in the same directory as the java file.  I know that it's connecting to the keystore because if I intentionally put in a bad password I get an exception about it.  With the correct password however I get no exceptions.

If I try to connect to this server using wss://serveraddress:8124, the connection just immediately fires the socket.onclose event.

Everything works perfectly fine if I take out the keystore and setssl stuff and connect using ws://.

This is the client side JS I'm using atm:

if (window.WebSocket) {
var socket = new WebSocket("wss://serveraddress:8124");
socket.onmessage = function(event) {
//alert("Received data from websocket: " + event.data);
jParsed = JSON.parse(event.data);
alert("JSON Recieved from server, Type: " + jParsed["type"] + " Message: " + jParsed["msg"]);
}

socket.onopen = function(event) {
alert("Web Socket opened");
//socket.send("Hello World");
};

socket.onclose = function(event) {
alert("Web Socket closed");
};
} else {
alert("Your browser does not support web sockets, UPGRADE!!!!");
}

function sendMsg(msg) {
//socket.send(msg);
var jsonObj = {"type": "msg",
"msg": msg};
socket.send(JSON.stringify(jsonObj));
}


In case it matters, I'm using an apache2 webserver, and this is being done over a https connection.

This is really annoying, cannot find any good examples anywhere of how to set this up properly.

Thanks for any assistance you can offer.

Tim Fox

unread,
Dec 24, 2013, 5:41:33 AM12/24/13
to ve...@googlegroups.com
A few things I would try:

1. Take a look at the SSL examples in the examples repo - make sure they work for you
2. Extend the SSL examples in the repo to set a keyStorePath -the chapter in the docs on SSL can guide you through this. Make sure that works for you
3. See how that differs from your client side example. What errors do you get (if any) in the browser dev console? (CTRL-SHIFT-J) in chrome? Perhaps the browser doesn't trust your certificate?
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Steven Hickerson

unread,
Dec 24, 2013, 11:36:05 AM12/24/13
to ve...@googlegroups.com
Thanks for the reply.  However I am not sure what examples repo you are referring to.  I've looked all over for some examples of setting up an SSL websocket connection with vert.x and have not been able to find a single one.  All the vert.x website has is notes saying that an SSL connection is possible for the HttpServer and follow the same API as the NetServer.

There are no errors showing in the dev console.  I've already tried that hoping it was some simple error that I could figure out from there.

I would not be surprised if it is a certifcate trust issue since I'm using selfsigned stuff, however, I don't get any prompt for it, have tried adding the https certificate (which shows the same issuer as the one I configured in the java keystore) to my list of trusted certificates, and that did not change anything.

Steven Hickerson

unread,
Dec 24, 2013, 12:09:31 PM12/24/13
to ve...@googlegroups.com
I should add that the https request handler works perfectly fine.  If I go to https://serveraddress:8124 it correctly servers the index.html page.  Also, I noticed in the dev console, that when it's set up in ssl mode, the websocket request acts exactly like it does when the server is not running.  This makes me think it's not even responding to the request for some reason, but I have no idea why.

Tim Fox

unread,
Dec 24, 2013, 12:20:49 PM12/24/13
to ve...@googlegroups.com
On 24/12/13 16:36, Steven Hickerson wrote:
Thanks for the reply.  However I am not sure what examples repo you are referring to.

Follow the "examples" link from http://vertx.io

Tim Fox

unread,
Dec 24, 2013, 12:22:45 PM12/24/13
to ve...@googlegroups.com
On 24/12/13 16:36, Steven Hickerson wrote:
Thanks for the reply.  However I am not sure what examples repo you are referring to.  I've looked all over for some examples of setting up an SSL websocket connection with vert.x and have not been able to find a single one.  All the vert.x website has is notes saying that an SSL connection is possible for the HttpServer and follow the same API as the NetServer.

There are no errors showing in the dev console.

So.. if you step through the client side JS code, it connects OK?

If there are no errors there are only two possibilities:

1) It's working
2) The client side code is not being executed

Steven Hickerson

unread,
Dec 24, 2013, 12:23:05 PM12/24/13
to ve...@googlegroups.com
That is what I figured you meant, however the only ssl example there is for NetServer, not Websockets.  And I have tried emulating how the NetServer ssl is configured to no avail.  As  I said, I have not been able to find any example of setting up ssl enabled websockets.

Steven Hickerson

unread,
Dec 24, 2013, 12:33:09 PM12/24/13
to ve...@googlegroups.com
No, as I said previously, all it does is immediately call the socket.close event.  It never calls the socket.open event.  Like I said in my last message, it acts exactly like it does if the server isn't running.  However it's obviously running because the http requestHandler is processing requests.  Only the websocketHandler is not responding when I have it set up for SSL.  It doesn't respond at ws:// or wss://, I tried both just to be sure.

Steven Hickerson

unread,
Dec 24, 2013, 12:41:12 PM12/24/13
to ve...@googlegroups.com
Ok well talking through it helped me come up with an idea.

It looks like this formatting does not work, but does not throw any errors:

vertx.createHttpServer().setSSL(true).setKeyStorePath("keystore.jks").setKeyStorePassword("mypass").websocketHandler(new Handler<ServerWebSocket>() {

I have to instead do:

HttpServer server = vertx.createHttpServer()
                                        .setSSL(true)
                                        .setKeyStorePath("keystore.jks")
                                        .setKeyStorePassword("jKspass");

                server.websocketHandler(new Handler<ServerWebSocket>() {


For some reason it does not recognize and create the websocketHandler if you string it together with the other settings, although it does recognize the requestHandler that way.

Thanks for your assistance.

Tim Fox

unread,
Dec 24, 2013, 12:48:15 PM12/24/13
to ve...@googlegroups.com
On 24/12/13 17:41, Steven Hickerson wrote:
Ok well talking through it helped me come up with an idea.

It looks like this formatting does not work, but does not throw any errors:

vertx.createHttpServer().setSSL(true).setKeyStorePath("keystore.jks").setKeyStorePassword("mypass").websocketHandler(new Handler<ServerWebSocket>() {

I have to instead do:

HttpServer server = vertx.createHttpServer()
                                        .setSSL(true)
                                        .setKeyStorePath("keystore.jks")
                                        .setKeyStorePassword("jKspass");

                server.websocketHandler(new Handler<ServerWebSocket>() {


For some reason it does not recognize and create the websocketHandler if you string it together with the other settings, although it does recognize the requestHandler that way.

Can you put the code that doesn't work in a gist and link to it here? I would like to try it out here, as it certainly should work if you chain methods.

Steven Hickerson

unread,
Dec 24, 2013, 1:20:10 PM12/24/13
to ve...@googlegroups.com
It's in the first message, but here it is again..

Randall Richard

unread,
Dec 24, 2013, 1:50:36 PM12/24/13
to ve...@googlegroups.com

As Tim suggested, to help isolate the problem, change the example to run with SSL enabled using your keystore.  One note, if you want to connect from a browser running on a different machine, change "localhost" in ws.html to point to the machine that's running the Vertx Websocket server.


Steven Hickerson

unread,
Dec 25, 2013, 2:46:23 AM12/25/13
to ve...@googlegroups.com
Thanks Randall, but as my code shows, this is pretty much exactly what I have already done.

Upon some more playing now that I found a case of it working.  I've made a further determination that it wasn't in fact the way the code was written, but is in fact an issue with how the certificate is being handled.

I can now reliably duplicate it working vs not working.  All that I have to do is go to a https page rendered by the vertx java server, and proceed with the certificate there, and then the secure websockets work.  If however, I try to go to the secure page served by the apache server which uses it's own certificate, then the secure websockets will not work.

I'm not sure how to get around this problem.  I don't know if I can use the same certificate apache uses in my java keystore or not.  All the examples of importing certificates show importing crt files where as the apache server is using a cem file.  They could very well be the same file type with different extensions, but I don't know enough about certificates to know that.

The browser does not appear to be configured to ask about trusting a self signed certificate for a websocket request.  This kind of sucks, as this is going to be a small website for me and a few friends to use on some things initially.  I don't really want to pay 70 dollars a year for a SSL certificate signed by a trusted authority just so that the browser wont reject it by default.  I don't even have a domain name for this website yet since it's still in the building and testing phase lol.

I'm going to keep poking around, hopefully there is some way for me to simply import the same certificate that apache uses, and it will be trusted for the browser session when visiting the main page and confirming to trust it.


--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/fLEwSCkOTkM/unsubscribe.
To unsubscribe from this group and all of its topics, send an email to vertx+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages