Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSL WebSocket exception - Received fatal alert: certificate_unknown #153

Open
supertick opened this issue Aug 7, 2021 · 49 comments
Open

Comments

@supertick
Copy link
Contributor

Hello !
Many thanks for nettosphere and its support !

I'm trying to get a self signed certificate with ssl to nettosphere working.
I checked in the unit tests of nettosphere for something appropriate and ended up with this :

        SelfSignedCertificate ssc = new SelfSignedCertificate();
        SslContext sslServer = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
        configBuilder.sslContext(sslServer);// .sslContext(sslCtx);
        configBuilder.enabledCipherSuites(sslServer.cipherSuites().toArray(new String[]{}));
        configBuilder.maxWebSocketFrameAggregatorContentLength(maxMsgSize);
        configBuilder.initParam("org.atmosphere.cpr.asyncSupport", "org.atmosphere.container.NettyCometSupport");
        configBuilder.initParam(ApplicationConfig.SCAN_CLASSPATH, "false");
        configBuilder.initParam(ApplicationConfig.PROPERTY_SESSION_SUPPORT, "true").port(port).host(address); // all
        configBuilder.maxChunkContentLength(maxMsgSize);
        configBuilder.maxWebSocketFrameSize(maxMsgSize);
        nettosphere = new Nettosphere.Builder().config(configBuilder.build()).build();        
        nettosphere.start();        

The results are mixed.
This exception is constantly being thrown

ERROR o.a.n.BridgeRuntime [BridgeRuntime.java:784] Unexpected and unhandled I/O Exception
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:477) ~[netty-all-4.1.66.Final.jar:4.1.66.Final]
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-all-4.1.66.Final.jar:4.1.66.Final]

Strangely it does not appear to affect the resource handlers I have written, however it does kill the
org.atmosphere.nettosphere.HttpStaticFileServerHandler

09:52:15.366 [nioEventLoopGroup-3-1] DEBUG i.n.c.AbstractChannelHandlerContext [AbstractChannelHandlerContext.java:305] An exception java.lang.NullPointerException
	at org.atmosphere.nettosphere.HttpStaticFileServerHandler.exceptionCaught(HttpStaticFileServerHandler.java:285)
	at org.atmosphere.nettosphere.BridgeRuntime.exceptionCaught(BridgeRuntime.java:785)
	at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:302)
	at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:281)
	at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:273)
	at io.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:1106)
	at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:302)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:381)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:829)

So in the end the browser won't load the site.

Any ideas, examples, or suggestions on how to remove this exception, but still have a "valid" self signed certificate ?
Thanks !

@thabach
Copy link
Member

thabach commented Aug 7, 2021

Hi there, you might want to give https://github.com/FiloSottile/mkcert a try, as an alternative to a self-signed certificate for local development.

@supertick
Copy link
Contributor Author

supertick commented Aug 8, 2021

I installed gvm
which allowed me to install go1.5
which allowed me to install mkcert
which I installed and ran the example.com example ..
which only produces pem files, which I had to convert to pkcs12 format
then convert that to a jks store :P

After all that - I don't get the trace stack anymore on the server Yay !
But it doesn't send back the static file (same end result as before) Booo !
image

It does send back a header - with a file size .. but no actual file
image

@supertick
Copy link
Contributor Author

Here is the debug logging I currently get :

17:47:27.305 [nioEventLoopGroup-3-1] DEBUG i.n.u.Recycler [Recycler.java:103] -Dio.netty.recycler.maxCapacityPerThread: 4096
17:47:27.305 [nioEventLoopGroup-3-1] DEBUG i.n.u.Recycler [Recycler.java:104] -Dio.netty.recycler.maxSharedCapacityFactor: 2
17:47:27.305 [nioEventLoopGroup-3-1] DEBUG i.n.u.Recycler [Recycler.java:105] -Dio.netty.recycler.linkCapacity: 16
17:47:27.306 [nioEventLoopGroup-3-1] DEBUG i.n.u.Recycler [Recycler.java:106] -Dio.netty.recycler.ratio: 8
17:47:27.306 [nioEventLoopGroup-3-1] DEBUG i.n.u.Recycler [Recycler.java:107] -Dio.netty.recycler.delayedQueue.ratio: 8
17:47:27.322 [nioEventLoopGroup-3-1] DEBUG i.n.b.AbstractByteBuf [AbstractByteBuf.java:63] -Dio.netty.buffer.checkAccessible: true
17:47:27.322 [nioEventLoopGroup-3-1] DEBUG i.n.b.AbstractByteBuf [AbstractByteBuf.java:64] -Dio.netty.buffer.checkBounds: true
17:47:27.324 [nioEventLoopGroup-3-1] DEBUG i.n.u.ResourceLeakDetectorFactory [ResourceLeakDetectorFactory.java:196] Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@555197f7
17:47:27.544 [nioEventLoopGroup-3-2] DEBUG i.n.h.s.SslHandler [SslHandler.java:1831] [id: 0x7d77ab04, L:/127.0.0.1:8888 - R:/127.0.0.1:45118] HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_128_GCM_SHA256
17:47:27.544 [nioEventLoopGroup-3-1] DEBUG i.n.h.s.SslHandler [SslHandler.java:1831] [id: 0x9d6f107c, L:/127.0.0.1:8888 - R:/127.0.0.1:45116] HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_128_GCM_SHA256
17:48:18.812 [nioEventLoopGroup-3-3] DEBUG i.n.h.s.SslHandler [SslHandler.java:1831] [id: 0x80572d11, L:/127.0.0.1:8888 - R:/127.0.0.1:45528] HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_128_GCM_SHA256

@supertick
Copy link
Contributor Author

Thanks for the suggestion ...

@supertick
Copy link
Contributor Author

curl is a little more informative ...

curl -vvv https://example.com:8888/index.html
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to example.com (127.0.0.1) port 8888 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: O=mkcert development certificate; OU=greg@t14-gperry (Greg Perry)
*  start date: Aug  8 00:30:11 2021 GMT
*  expire date: Nov  8 01:30:11 2023 GMT
*  subjectAltName: host "example.com" matched cert's "example.com"
*  issuer: O=mkcert development CA; OU=greg@t14-gperry (Greg Perry); CN=mkcert greg@t14-gperry (Greg Perry)
*  SSL certificate verify ok.
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET /index.html HTTP/1.1
> Host: example.com:8888
> User-Agent: curl/7.58.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/1.1 200 OK
< content-length: 7512
< Content-Type: text/html
< date: Sun, 08 Aug 2021 01:06:52 GMT
< expires: Sun, 08 Aug 2021 01:07:52 GMT
< cache-control: private, max-age=60
< last-modified: Thu, 05 Aug 2021 02:29:04 GMT
< 
* TLSv1.3 (IN), TLS Unknown, Unknown (21):
* TLSv1.3 (IN), TLS alert, Client hello (1):
* transfer closed with 7512 bytes remaining to read
* stopped the pause stream!
* Closing connection 0
* TLSv1.3 (OUT), TLS Unknown, Unknown (21):
* TLSv1.3 (OUT), TLS alert, Client hello (1):
curl: (18) transfer closed with 7512 bytes remaining to read
greg@t14-gperry:~/github/mkcert$

so the 7512 bytes never come .....
The headers are exchanged so it seems that TLS over HTTP1.1 is worky
No exceptions, no errors, but no data

@supertick
Copy link
Contributor Author

Any thoughts for this ?
TLS works headers are exchanged, but exceptions are coming from netty + no static file returned ?

@thabach
Copy link
Member

thabach commented Aug 17, 2021

I don’t quite get why this is configured as a web socket, or is it? The title has it declared as such. U try to serve a simple GET request right?

@supertick
Copy link
Contributor Author

The js of the client initially is served from static pages .. I'm using the Atmosphere javascript client - https://github.com/Atmosphere/atmosphere-javascript

So, yes - a handler is set to serve the static page, the page loads in the browser, executes the js client which opens the websocket. It works without SSL, but not with SSL ...

@thabach
Copy link
Member

thabach commented Aug 17, 2021

Gotya, could you run your curl -v with --ignore-content-length and paste the output? Does a similar curl request against the working version reply with the same content-length for your index.html?

@supertick
Copy link
Contributor Author

supertick commented Apr 28, 2022

heh, sorry about the extremely long pause ... apparently some pandemic got loose ...
@thabach - ya ... works fine under http

curl -k -vvv --ignore-content-length http://example.com:8888/index.html
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to example.com (127.0.0.1) port 8888 (#0)
> GET /index.html HTTP/1.1
> Host: example.com:8888
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-length: 7560
< Content-Type: text/html
< date: Thu, 28 Apr 2022 06:13:47 GMT
< expires: Thu, 28 Apr 2022 06:14:47 GMT
< cache-control: private, max-age=60
< last-modified: Sat, 05 Mar 2022 17:24:32 GMT
* no chunk, no close, no size. Assume close to signal end
< 
<!doctype html>
<html lang="en" ng-app="mrlapp">
    <head>
        <meta charset="utf-8">
    ( full html page )

All bytes are returned specifically 7560 of them ...
but switching to use ssl - I get this ..

curl -k -vvv --ignore-content-length https://example.com:8888/index.html
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to example.com (127.0.0.1) port 8888 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=localhost
*  start date: Apr 28 06:17:43 2021 GMT
*  expire date: Dec 31 23:59:59 9999 GMT
*  issuer: CN=localhost
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET /index.html HTTP/1.1
> Host: example.com:8888
> User-Agent: curl/7.58.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/1.1 200 OK
< content-length: 7560
< Content-Type: text/html
< date: Thu, 28 Apr 2022 06:18:02 GMT
< expires: Thu, 28 Apr 2022 06:19:02 GMT
< cache-control: private, max-age=60
< last-modified: Sat, 05 Mar 2022 17:24:32 GMT
* no chunk, no close, no size. Assume close to signal end
< 
* TLSv1.3 (IN), TLS Unknown, Unknown (21):
* TLSv1.3 (IN), TLS alert, Client hello (1):
* Closing connection 0
* TLSv1.3 (OUT), TLS Unknown, Unknown (21):
* TLSv1.3 (OUT), TLS alert, Client hello (1):

It returns the correct byte count ... but no data

@supertick
Copy link
Contributor Author

can we re-open this ?

@supertick
Copy link
Contributor Author

supertick commented Apr 28, 2022

interestingly, my custom resource works fine in https
configBuilder.resource("/api", this);

curl -k -vvv --ignore-content-length https://example.com:8888/api/service/runtime/getUptime
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to example.com (127.0.0.1) port 8888 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=localhost
*  start date: Apr 28 06:17:43 2021 GMT
*  expire date: Dec 31 23:59:59 9999 GMT
*  issuer: CN=localhost
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET /api/service/runtime/getUptime HTTP/1.1
> Host: example.com:8888
> User-Agent: curl/7.58.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/1.1 200 OK
< Content-Type:application/json
< Transfer-Encoding:chunked
< Server:Nettosphere/3.2.5
< Cache-Control:no-store, no-cache, must-revalidate
< X-Atmosphere-first-request:true
< Connection:Keep-Alive
< Expires:-1
< Pragma:no-cache
< X-Atmosphere-tracking-id:68ae2672-b974-47df-b7fc-773b81bd2b69
< 
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* Connection #0 to host example.com left intact
"0 days 0 hours 10 minutes 5 seconds"

but any static file with the default file path resource - does not work
e.g. index.html inside this path
configBuilder.resource("./src/main/resources/resource/WebGui/app");

@jfarcand jfarcand reopened this Apr 28, 2022
@jfarcand
Copy link
Member

@supertick If you can share a github's repo with a test case I will take a look

@supertick
Copy link
Contributor Author

Easy :)

https://github.com/MyRobotLab/nettosphere-ssl
I tried to provide the simplest example...

      boolean ssl = true;
      if (ssl) {
        SelfSignedCertificate ssc = new SelfSignedCertificate("localhost");
        SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey(), null).build();
        configBuilder.sslContext(sslCtx);
      }

      configBuilder.resource("./");
      Nettosphere nettosphere = new Nettosphere.Builder().config(configBuilder.build()).build();
      nettosphere.start();

ssl = false returns the index.html correctly
ssl = true does not

@thabach
Copy link
Member

thabach commented May 1, 2022

@jfarcand I digged a bit too, not sure why the HttpStaticFileServerHandler in the presence of SSL chooses to send the file chunk-encoded, maybe a hint:

image

Cheers.

@thabach
Copy link
Member

thabach commented May 1, 2022

btw, for the test-case of @supertick to work, I needed to add the below to his pom.xml for the self-signed certificate creation:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.49</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.49</version>
</dependency>

@supertick
Copy link
Contributor Author

@jfarcand any ideas ?

@jfarcand
Copy link
Member

jfarcand commented May 3, 2022

@supertick On it today

@jfarcand
Copy link
Member

jfarcand commented May 4, 2022

@thabach Have you been able to pass this exception? I think you are right with the code...I forgot how to setup Nettosphere properly hahahaha

06:45:02.163 [nioEventLoopGroup-3-2] ERROR org.atmosphere.nettosphere.BridgeRuntime - Unexpected and unhandled I/O Exception
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:477)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313)
	at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
	at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:681)
	at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:636)
	at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:454)
	at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:433)
	at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:637)
	at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:296)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1342)
	at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1235)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1284)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:446)
	... 17 common frames omitted

@supertick
Copy link
Contributor Author

@thabach - I updated the pom in the example with the bouncy castle dep. Also, I updated the poms spec references to java 11 (from java 8) ... I'm using Java 11 locally anyway, and see one of the badges on Nettosphere's page as green.
I tried to make the sample as simple as possible. In another project I can tell that the non-static file resource handlers appear to be working, only the static resource handler explodes.

@thabach
Copy link
Member

thabach commented May 4, 2022

@jfarcand, with @supertick's pom changes, I can start his test and then I do a:

curl -k -v https://localhost:8080/index.html

to reproduce the issue with the infamous transfer closed with 47 bytes remaining to read. I don't get the unknown Certificate Authority exception, but as of it being a self-signed certificate, the following:

* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

which is probably the very same issue you see in your client. Therefore I employ the -k switch in curl for it to go on.

@supertick, gotya, yes I think the culprit is indeed the HttpStaticFileServerHandler with an emphasis on static.

@thabach
Copy link
Member

thabach commented May 4, 2022

@jfarcand, it does not work on exercising the standard/non-ssl if-branch from the above code for the https-call. I just tried. We need you 😃 ...

@jfarcand
Copy link
Member

jfarcand commented May 5, 2022

@thabach THANKS!!!! I always like to work with you! Looking at it today! Thanks @supertick

@jfarcand
Copy link
Member

jfarcand commented May 6, 2022

@supertick Fixed in 3.2.6-SNAPSHOT and let me know the result I will cut the official release

@supertick
Copy link
Contributor Author

My super quick way to test - adding the source test to a clean nettosphere
git checkout 4a5d587

image
noWorky :(
image

curl -k https://localhost:8080/index.html
curl: (52) Empty reply from server

@jfarcand jfarcand reopened this May 10, 2022
@jfarcand
Copy link
Member

@supertick I do get

❯ curl -k https://localhost:8080/index.html
<html>
<head/>
<body>
	hello !
</body>
</html>

But I do experience issue when I use Chrome

@jfarcand
Copy link
Member

❯ curl -vvv https://127.0.0.1:8080/index.html
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

I think in my case I just need to sign the cert

@supertick
Copy link
Contributor Author

supertick commented May 10, 2022

Hmmm ... 🤔
is your setup like this ?

      if (ssl) {
        SelfSignedCertificate ssc = new SelfSignedCertificate("localhost");
        SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey(), null).build();
        configBuilder.sslContext(sslCtx);
      }

      configBuilder.resource("./");
      Nettosphere nettosphere = new Nettosphere.Builder().config(configBuilder.build()).build();
      nettosphere.start();

I've tried curl & wget ... neither get responses ...

--2022-05-10 15:28:51--  (try: 3)  https://localhost:8080/index.html
Connecting to localhost (localhost)|127.0.0.1|:8080... connected.
WARNING: cannot verify localhost's certificate, issued by ‘CN=localhost’:
  Self-signed certificate encountered.
HTTP request sent, awaiting response... No data received.
Retrying.

--2022-05-10 15:28:54--  (try: 4)  https://localhost:8080/index.html
Connecting to localhost (localhost)|127.0.0.1|:8080... connected.
WARNING: cannot verify localhost's certificate, issued by ‘CN=localhost’:
  Self-signed certificate encountered.
HTTP request sent, awaiting response... No data received.
Retrying.

@jfarcand
Copy link
Member

@supertick I use the latest Nettosphere snapshot and just added to your pom.xml

		 <dependency>
		     <groupId>com.sun.activation</groupId>
		     <artifactId>javax.activation</artifactId>
		     <version>1.2.0</version>
		 </dependency>

@supertick
Copy link
Contributor Author

added activation dep .... WORKY !

curl  -k https://localhost:8080/index.html
<html>
<head/>
<body>
        hello !
</body>
</html>

Thanks @jfarcand 👍

@jfarcand
Copy link
Member

@supertick I've released 3.2.6!

@supertick
Copy link
Contributor Author

supertick commented May 12, 2022

Uh oh ...
Did you have non-valid reflective access in the update ?
Running without ssl .. I now get the following errors.

java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled
	at io.netty.util.internal.ReflectionUtil.trySetAccessible(ReflectionUtil.java:31)
	at io.netty.util.internal.PlatformDependent0$4.run(PlatformDependent0.java:233)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:227)
	at io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:289)
	at io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:92)
	at io.netty.channel.group.DefaultChannelGroup.<init>(DefaultChannelGroup.java:48)
	at io.netty.channel.group.DefaultChannelGroup.<init>(DefaultChannelGroup.java:74)
	at org.atmosphere.nettosphere.Nettosphere.<clinit>(Nettosphere.java:67)
	at org.atmosphere.nettosphere.Nettosphere$Builder.build(Nettosphere.java:201)
	at org.myrobotlab.service.WebGui.start(WebGui.java:1100)
	at org.myrobotlab.service.WebGui.startService(WebGui.java:1151)
	at org.myrobotlab.service.WebGui.main(WebGui.java:1291)

The exception is thrown when initializing the default channel group..
public final class Nettosphere {

    public final static String FLASH_SUPPORT = Nettosphere.class.getName() + ".enableFlash";
    private static final Logger logger = LoggerFactory.getLogger(Nettosphere.class);
    private static final ChannelGroup ALL_CHANNELS = new DefaultChannelGroup("atmosphere",
            ImmediateEventExecutor.INSTANCE);

My configuration is pretty straightforward - this used to work

    configBuilder.resource("./resource");
    configBuilder.resource("/api", this);
    configBuilder.maxWebSocketFrameAggregatorContentLength(maxMsgSize);
    configBuilder.initParam("org.atmosphere.cpr.asyncSupport", "org.atmosphere.container.NettyCometSupport");
    configBuilder.initParam(ApplicationConfig.SCAN_CLASSPATH, "false");
    configBuilder.initParam(ApplicationConfig.PROPERTY_SESSION_SUPPORT, "true").port(port).host(address); // all
    configBuilder.maxChunkContentLength(maxMsgSize);
    configBuilder.maxWebSocketFrameSize(maxMsgSize);

I'll keep testing (Using Java 11 btw - I know reflection access becomes more problematic in future jdks)

It seems as now, the websocket after getting connected, is immediately disconnected (not running ssl)
Reverting back to nettosphere 3.2.1 where websockets were worky.

@jfarcand
Copy link
Member

euh...what is that :-) Can you try 3.2.5?

@supertick
Copy link
Contributor Author

supertick commented May 12, 2022

The reflective warning is apparently not an error - netty/netty#7817
I went back and validated it is giving the same "warning" in 3.2.1 (and probably not relevant - its logged at DEBUG level)
However,

The issue is:
3.2.5 & 3.2.1 - do not immediately disconnect websockets
3.2.6 - does 😢

this is new behavior with 3.2.6

@supertick
Copy link
Contributor Author

3.2.1 & 3.2.5 ws connection as expected

git checkout 925feaa65d0c144d61acd83fea34397ecad6f1ea
prepare release nettosphere-project-3.2.5
$ wscat -c http://localhost:8080/api
Connected (press CTRL+C to quit)
< X

3.2.6 immediate disconnect

$ wscat -c http://localhost:8080/api
error: socket hang up

@supertick
Copy link
Contributor Author

In order to show what is happening easily, I forked your repo and just added a quick test file
It's on master - https://github.com/supertick/nettosphere/blob/master/server/src/main/java/NettoSsl.java
You can switch between the 3.2.5 and 3.2.6 releases:

on
3.2.5 - gets a static resource, and will suspend a websocket connection

switch to
3.2.6 - gets a static resource, but immediately disconnects on a websocket connection

Hope this helps.

@jfarcand
Copy link
Member

@supertick Yep that helps. So you are ok with 3.2.5 then. I will rollback the latest changes and release 3.2.7 asap

@supertick
Copy link
Contributor Author

I think the current state is:
3.2.5 - websockets work, but static resource to ssl returns nothing
3.2.6 - static resource works with ssl, but websockets do not work

jfarcand added a commit that referenced this issue May 16, 2022
jfarcand added a commit that referenced this issue May 16, 2022
@jfarcand
Copy link
Member

@supertick Can you try 3.2.7-SNAPSHOT? Couples of tests failing but both ws and ssl seems to work fine

@supertick
Copy link
Contributor Author

yessir

@supertick
Copy link
Contributor Author

supertick commented May 19, 2022

3.2.7-SNAPSHOT

  • worky for non ssl static content ✔️
  • worky for non ssl ws ✔️
  • worky for ssl static content ❌
  • worky for ssl ws ✔️

This might be the same results as 3.2.5
Let me know if you want me to test some other functionality

@jfarcand
Copy link
Member

@supertick OK I think I have it fixed. Let me know and SUPER thanks for the help!

jfarcand added a commit that referenced this issue May 19, 2022
@jfarcand jfarcand added the 3.2.7 label May 30, 2022
@supertick
Copy link
Contributor Author

I tested 3.2.7 from maven central ... still no worky 😢

@supertick
Copy link
Contributor Author

3.2.7 maven central release
no worky for non ssl static content ❌

haven't regression tested the rest yet ...

@jfarcand
Copy link
Member

Let me know what you tested. For me everything works as expected

@jfarcand jfarcand reopened this Jun 14, 2022
@supertick
Copy link
Contributor Author

super simple test - single file, testing with java 11
https://github.com/MyRobotLab/netto-test

4 files

  • NettoSsl.java (configures and starts nettosphere server)
  • pom.xml dependencies
  • index.html static file in the root
  • favicon.ico static file in the root

I'm using eclipse - start project - start server with 3.2.1 goto http://localhost:8080/index.html
get "hello world !" in browser

switch to 3.2.7
image

I could document curl requests - but I suspect they are the same as before

@supertick
Copy link
Contributor Author

I think there might be 4 use cases to test

  • ssl static
  • wss
  • non-ssl static
  • ws
    currently, I'm only testing ssl being on or off for both static and websockets (no combination)
    but it's never passed the 4 possibilities

@supertick
Copy link
Contributor Author

Ahoy !
can you replicate the issue ?

@supertick
Copy link
Contributor Author

I wonder if this is a dependency conflict issue 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants