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

tls: OpenSSL errors with many tls socket writes #1595

Closed
mscdex opened this issue May 3, 2015 · 6 comments
Closed

tls: OpenSSL errors with many tls socket writes #1595

mscdex opened this issue May 3, 2015 · 6 comments
Labels
tls Issues and PRs related to the tls subsystem.

Comments

@mscdex
Copy link
Contributor

mscdex commented May 3, 2015

Recently while trying to create a benchmark for the JS Duplex stream compatibility for tls.connect(), I discovered an issue while trying to perform > 10-ish successive writes to the tls wrapped socket. The test case to reproduce this is in #1594.

The error I get is:

Error: 139779539269504:error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac:../deps/openssl/openssl/ssl/s3_pkt.c:521:

I'm not sure why it's using SSL3 in the first place since I thought 2 and 3 were disabled by default. So I tried forcing TLSv1 by setting secureProtocol: 'TLSv1_method' in the tls.connect() options, which instead causes this error:

events.js:141
      throw er; // Unhandled 'error' event
            ^
Error: socket hang up
    at TLSSocket.onHangUp (_tls_wrap.js:951:19)
    at TLSSocket.g (events.js:257:16)
    at emitNone (events.js:72:20)
    at TLSSocket.emit (events.js:163:7)
    at endReadableNT (_stream_readable.js:890:12)
    at doNTCallback2 (node.js:436:9)
    at process._tickCallback (node.js:350:17)
    at Duplex.<anonymous> (_stream_wrap.js:38:18)
    at emitOne (events.js:77:13)
    at Duplex.emit (events.js:166:7)
@mscdex
Copy link
Contributor Author

mscdex commented May 3, 2015

/cc @indutny

@mscdex mscdex added the tls Issues and PRs related to the tls subsystem. label May 3, 2015
@bnoordhuis
Copy link
Member

I'm not sure why it's using SSL3 in the first place since I thought 2 and 3 were disabled by default.

OpenSSL uses the same code for reading and writing SSLv3 and TLSv1.x frames. SSL and TLS are largely the same wire protocol, the differences are in the supported extensions and cipher suites.

@shigeki
Copy link
Contributor

shigeki commented May 5, 2015

Sorry for my previous blank comment. This issue comes from a tiny bug in JSStream::DoWrite where it always sends the first buffer so that its data becomes an invalid broken SSL record data. It can be fixed the following patch.

diff --git a/src/js_stream.cc b/src/js_stream.cc
index 09c4f58..6b7c406 100644
--- a/src/js_stream.cc
+++ b/src/js_stream.cc
@@ -89,7 +89,7 @@ int JSStream::DoWrite(WriteWrap* w,

   Local<Array> bufs_arr = Array::New(env()->isolate(), count);
   for (size_t i = 0; i < count; i++)
-    bufs_arr->Set(i, Buffer::New(env(), bufs[0].base, bufs[0].len));
+    bufs_arr->Set(i, Buffer::New(env(), bufs[i].base, bufs[i].len));

   Local<Value> argv[] = {
     w->object(),

@mscdex Your test of #1594 does not have server.close() and assert check. I modified your test as below. Is it good for you?

diff --git a/test/parallel/test-tls-connect-stream-writes.js b/test/parallel/test-tls-connect-stream-writes.js
index 3c9fecc..0bf1db1 100644
--- a/test/parallel/test-tls-connect-stream-writes.js
+++ b/test/parallel/test-tls-connect-stream-writes.js
@@ -1,4 +1,5 @@
-var fs = require('fs'),
+var assert = require('assert'),
+    fs = require('fs'),
     path = require('path'),
     tls = require('tls'),
     stream = require('stream'),
@@ -12,8 +13,14 @@ var cert_dir = path.resolve(__dirname, '../fixtures'),
                 cert: fs.readFileSync(cert_dir + '/test_cert.pem'),
                 ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ],
                 ciphers: 'AES256-GCM-SHA384' };
-
-server = tls.createServer(options);
+var content = 'hello world';
+var recv_bufs = [];
+var send_data = '';
+server = tls.createServer(options, function(s) {
+  s.on('data', function(c) {
+    recv_bufs.push(c);
+  });
+});
 server.listen(common.PORT, function() {
   var raw = net.connect(common.PORT);

@@ -43,8 +50,16 @@ server.listen(common.PORT, function() {
     socket: p,
     rejectUnauthorized: false
   }, function() {
-    for (var i = 0; i < 50; ++i)
-      socket.write('hello world');
+    for (var i = 0; i < 50; ++i) {
+      socket.write(content);
+      send_data += content;
+    }
     socket.end();
+    server.close();
   });
 });
+
+process.on('exit', function() {
+  var recv_data = (Buffer.concat(recv_bufs)).toString();
+  assert.strictEqual(send_data, recv_data);
+});

@mscdex
Copy link
Contributor Author

mscdex commented May 5, 2015

@shigeki The test changes look fine to me.

@indutny
Copy link
Member

indutny commented May 5, 2015

@shigeki please file a PR, LGTM

shigeki pushed a commit to shigeki/node that referenced this issue May 6, 2015
The index of buffer to write in JSStream was always 0 by mistake. This
fix was to use increment index of buffer arrays.
The test was originally made by Brian White in nodejs#1594.

Fixes: nodejs#1595
Fixes: nodejs#1594
shigeki pushed a commit that referenced this issue May 6, 2015
The index of buffer to write in JSStream was always 0 by mistake. This
fix was to use increment index of buffer arrays.
The test was originally made by Brian White in #1594.

Fix: #1595
Fix: #1594
PR-URL: #1635
Reviewed-By: Fedor Indutny <fedor@indutny.com>
@brendanashworth
Copy link
Contributor

Also fixed in #1635.

Fishrock123 pushed a commit to Fishrock123/node that referenced this issue May 19, 2015
The index of buffer to write in JSStream was always 0 by mistake. This
fix was to use increment index of buffer arrays.
The test was originally made by Brian White in nodejs#1594.

Fix: nodejs#1595
Fix: nodejs#1594
PR-URL: nodejs#1635
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tls Issues and PRs related to the tls subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants