-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
TLS Alert when using smtp-protocol server with Java client #4072
Comments
A failing handshake (captured by -l debug; I've only added a few comments about the weird-looking HandshakeType and the Alert, and removed the separating '-', as they format the text). Observe that the Alert is printed at the same time as the last handshake messages sent by the server - the Alert was already in the buffer of the outgoing data before the handshake got on the wire, so it is clearly the server decision to close TLS. You can also capture and observe any succeeding connection, too - the only difference is the random data (key material, session-id, random), and the absence of the Alert at the end of the exchange: tserver for socket 10.9.21.3:55708 tls id: 4000 receives 247 bytes ContentType: 22 ContentType: 22 ContentType: 22 ContentType: 22 ContentType: 22 ContentType: 22ProtocolVersion: 0303 ContentType: 20 -- changing cipher - now client comms will be encrypted ContentType: 22 ContentType: 20 -- changing cipher - now server comms will be encrypted ContentType: 22 ContentType: 21 -- Alert |
Reproducible with TLSv1, TLSv1.1 and TLSv1.2 as selected by the Java client |
doesn't reproduce the issue. This seems to indicate that the issue is entirely due to how smtp-protocol adds TLS to the existing connection. If this is so, suggest the correct way to wrap the plain-text socket to continue the communication over TLS. |
It may well be an issue with net.Server, not tls. If I start one tls server per worker (see tls2.txt), but wire the socket in the same manner, two important things occur: 1. I never see the Java client fail; 2. I never see the condition similar to index > 1 in tls.js (see the function on secureConnection calling sec.end() in tls.txt - I did notice that being invoked more than once in the smtp-protocol case, but it seems to always be invoked more than once on the tserver created for a succeeding connection, so I didn't think it's the cause of the failure). |
I think I can boil this down to incorrect usage of net.Server by smtp-protocol. When creating a tlsServer, they listen on port 0 (which means to choose a random port), yet exclusive is left default. Thus multiple workers possibly may end up choosing the same random port (I don't know how to check whether this is happening, but the symptoms seem to add up to this story), and they will start sharing incoming connections. When this happens, the connection may end up being served by the "wrong" worker (smtp-protocol TLS processing logic is tied to the worker that received STARTTLS command), it will fire another secureConnection event (condition index > 0 in tls.js), and smtp-protocol will close that connection (on 'secureConnection' it calls sec.end()), which will be seen by the client as a nice termination of connection by server (the close_notify Alert). Testing with exclusive=true. If this works as expected, will close as not a node.js bug (but need to propagate the fix to smtp-protocol). |
node.js 4.2.2, module smtp-protocol, created a server. When starttls command is received, a TLS handshake occurs. With multiple workers in use, the server intermittently sends Alert close_notify (as captured by Java client TLS debug) after handshake and before any application data arrives (I can see the network data containing the Alert arrives before the application data is sent). This is easily reproducible with Java client.
($ node --version
v4.2.2
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
$ uname -a
Linux hostname 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux)
I have reduced the server side to mimic just the way the ssl connection is treated by smtp-protocol (i.e. redirection through a new tls server started on localhost), and made the TLS server echo the incoming data back.
(see tls.txt attached - save to tls.js)
start like so:
./tls.js -w 1 -k key_cert.pem -c cert.pem
works fine.
./tls.js -w 4 -k key_cert.pem -c cert.pem
Intermittent failure. Specify -l debug to see the TLS handshake exchanges.
(i.e.:
$ java -cp . -DCONCURRENCY=4 blah.HTTPSStd otherhost 25125
EOF was not expected at this time)
The blah.HTTPSStd is the rendition of an HTTPS-like client (to test that it is a correctly operating TLS client just point at google.com 443) using standard JDK7 classes:
save the HTTPSStd.txt (attached in the next comment) to blah/HTTPSStd.java
compile with $ javac blah/HTTPSStd.java
run with $ java -cp . -DCONCURRENCY=4 blah.HTTPSStd otherhost 25125
to get extensive TLS diagnostics from the client side (really a lot, and not easy to contemplate because of concurrency involved), run with $ java -cp . -DCONCURRENCY=4 -Djavax.net.debug=all blah.HTTPSStd otherhost 25125
The text was updated successfully, but these errors were encountered: