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

Node.js v0.12.7 session resumption (caching) is not working #3132

Closed
Fr1ar opened this issue Sep 30, 2015 · 6 comments
Closed

Node.js v0.12.7 session resumption (caching) is not working #3132

Fr1ar opened this issue Sep 30, 2015 · 6 comments
Labels
question Issues that look for answers. tls Issues and PRs related to the tls subsystem.

Comments

@Fr1ar
Copy link

Fr1ar commented Sep 30, 2015

I'm trying to run node.js with session resumption, but it doesn't work.

var tls = require('tls');
var fs = require('fs');
var credentials = {
    key: fs.readFileSync('/etc/ssl/private.key'),
    cert: fs.readFileSync('/etc/ssl/node/domain.crt'),
    ca: [ fs.readFileSync('/etc/ssl/node/root.crt') ],
    honorCipherOrder: true,
    ciphers: 'AES256+EECDH:AES256+EDH:!aNULL'
};
var server = tls.createServer(credentials);
server.listen(443, '172.64.51.208');

Everithing works fine with tickets:

$ openssl s_client -connect DOMAINNAME.COM:443 -reconnect 2>/dev/null | grep Session-ID:

Output:

    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883
    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883
    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883
    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883
    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883
    Session-ID: 6ED6DF08F215B3EE1059469314F1A7AE5429DF30F9D1DD8F80D79EA8F369A883

However, with -no_ticket option it doesn't work:

$ openssl s_client -connect DOMAINNAME.COM:443 -reconnect -no_ticket 2>/dev/null | grep Session-ID:

Output:

    Session-ID: F78DAC5F641D784BED89B294D455A58A6865949737E2938A20F1CD4D0AE3B843
    Session-ID: 3ADCB81F4C86AEA45EA26C1A482A8FFD5A8EDAA7E18E080CC69548A9CF21C425
    Session-ID: BF694439560F429B1DAADCDCBDB6059574809D15690ED369ADD56C5FAD2EAE8D
    Session-ID: 5FC2773475D4F2725DCE5951C5B188A4B3FCC7913FB710FD3901E937734FD735
    Session-ID: 895149C5EFF7FC6B233E5F1C78A2E01AE46D091D46A8F0EA1C71E357B3591913
    Session-ID: 1005FB0D046B030F6216BED0D546F9B9DE27A5630ADBC2B87AA5C497FD7335B5

What am I doing wrong?

@silverwind
Copy link
Contributor

Pretty sure you need to manage session ids through the newSession and resumeSession events on the server, see: https://strongloop.com/strongblog/improve-the-performance-of-the-node-js-https-server/.

@silverwind silverwind added question Issues that look for answers. tls Issues and PRs related to the tls subsystem. labels Sep 30, 2015
@Fr1ar
Copy link
Author

Fr1ar commented Oct 1, 2015

@silverwind Unfortunately it didn't help and even made situation worse :(

var tls = require('tls');
var fs = require('fs');
var credentials = {
    key: fs.readFileSync('/etc/ssl/private.key'),
    cert: fs.readFileSync('/etc/ssl/node/domain.crt'),
    ca: [ fs.readFileSync('/etc/ssl/node/root.crt') ],
    honorCipherOrder: true,
    ciphers: 'AES256+EECDH:AES256+EDH:!aNULL'
};
var server = tls.createServer(credentials);

// ----------------------
var tlsSessionStore = {};
var server = tls.createServer(credentials);
server.on('newSession', function(id, data) {
    tlsSessionStore[id] = data;
});
server.on('resumeSession', function(id, cb) {
    cb(null, tlsSessionStore[id] || null);
});
// ----------------------

server.listen(443, '172.64.51.208');

Check what happened:

$ openssl s_client -connect DOMAINNAME.COM:443 -reconnect -no_ticket -CAfile /etc/ssl/node/root.crt

Output:

CONNECTED(00000003)
depth=3 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify return:1
depth=2 C = CN, O = WoSign CA Limited, CN = Certification Authority of WoSign
verify return:1
depth=1 C = CN, O = WoSign CA Limited, CN = WoSign CA Free SSL Certificate G2
verify return:1
depth=0 CN = DOMAINNAME.COM
verify return:1

... and that's it. Nothing happens after this output. Let's try to get an additional information:

$ openssl s_client -connect DOMAINNAME.COM:443 -reconnect -msg -debug -state -no_ticket -CAfile /etc/ssl/node/root.crt

Can you explain this output and why session resumption with cache doesn't work?

CONNECTED(00000003)
SSL_connect:before/connect initialization
write to 0xcfc510 [0xcfc590] (313 bytes => 313 (0x139))
0000 - 16 03 01 01 34 01 00 01-30 03 03 24 e6 48 39 11   ....4...0..$.H9.
[REMOVED]
0130 - 02 02 02 03 00 0f 00 01-01                        .........
>>> TLS 1.2  [length 0005]
    16 03 01 01 34
>>> TLS 1.2 Handshake [length 0134], ClientHello
    01 00 01 30 03 03 24 e6 48 39 11 bd b2 5e fc 5e
[REMOVED]
    02 04 03 03 01 03 02 03 03 02 01 02 02 02 03 00
    0f 00 01 01
SSL_connect:SSLv2/v3 write client hello A
read from 0xcfc510 [0xd01af0] (7 bytes => 7 (0x7))
0000 - 16 03 03 00 59 02                                 ....Y.
0007 - <SPACES/NULS>
<<< ??? [length 0005]
    16 03 03 00 59
read from 0xcfc510 [0xd01afa] (87 bytes => 87 (0x57))
0000 - 00 55 03 03 4a 97 c8 44-4f f7 ab de 15 87 8d 16   .U..J..DO.......
[REMOVED]
0050 - 0b 00 04 03 00 01 02                              .......
<<< TLS 1.2 Handshake [length 0059], ServerHello
    02 00 00 55 03 03 4a 97 c8 44 4f f7 ab de 15 87
[REMOVED]
    00 00 0b 00 04 03 00 01 02
SSL_connect:SSLv3 read server hello A
read from 0xcfc510 [0xd01af3] (5 bytes => 5 (0x5))
0000 - 16 03 03 11 d9                                    .....
<<< ??? [length 0005]
    16 03 03 11 d9
read from 0xcfc510 [0xd01af8] (4569 bytes => 4245 (0x1095))
0000 - 0b 00 11 d5 00 11 d2 00-05 b9 30 82 05 b5 30 82   ..........0...0.
[REMOVED]
0130 - 41 5a c1 3d 60 ed 9f bb-b8 6d 9b ce a9 6a 16 3f   AZ.=`....m...j.?
0140 - 7e ea 06 f1                                       ~...
<<< TLS 1.2 Handshake [length 11d9], Certificate
    0b 00 11 d5 00 11 d2 00 05 b9 30 82 05 b5 30 82
[REMOVED]
    9b a5 92 bf f8 41 5a c1 3d 60 ed 9f bb b8 6d 9b
    ce a9 6a 16 3f 7e ea 06 f1
depth=3 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify return:1
depth=2 C = CN, O = WoSign CA Limited, CN = Certification Authority of WoSign
verify return:1
depth=1 C = CN, O = WoSign CA Limited, CN = WoSign CA Free SSL Certificate G2
verify return:1
depth=0 CN = DOMAINNAME.COM
verify return:1
SSL_connect:SSLv3 read server certificate A
read from 0xcfc510 [0xd01af3] (5 bytes => 5 (0x5))
0000 - 16 03 03 02 4d                                    ....M
<<< ??? [length 0005]
    16 03 03 02 4d
read from 0xcfc510 [0xd01af8] (589 bytes => 589 (0x24D))
0000 - 0c 00 02 49 03 00 17 41-04 a3 04 23 b9 e6 3f d8   ...I...A...#..?.
[REMOVED]
0240 - 90 ee 8a ed 05 f6 ca 4a-b5 f2 63 39 33            .......J..c93
<<< TLS 1.2 Handshake [length 024d], ServerKeyExchange
    0c 00 02 49 03 00 17 41 04 a3 04 23 b9 e6 3f d8
[REMOVED]
    90 ee 8a ed 05 f6 ca 4a b5 f2 63 39 33
SSL_connect:SSLv3 read server key exchange A
read from 0xcfc510 [0xd01af3] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 04                                    .....
<<< ??? [length 0005]
    16 03 03 00 04
read from 0xcfc510 [0xd01af8] (4 bytes => 4 (0x4))
0000 - 0e                                                .
0004 - <SPACES/NULS>
<<< TLS 1.2 Handshake [length 0004], ServerHelloDone
    0e 00 00 00
SSL_connect:SSLv3 read server done A
>>> ??? [length 0005]
    16 03 03 00 46
>>> TLS 1.2 Handshake [length 0046], ClientKeyExchange
    10 00 00 42 41 04 96 66 2b af 0c cf 33 f5 61 f7
    c8 76 5c bb dc ad e8 5e 4e 94 5e 5a 3e 0d 76 c1
    48 25 7a 9e 47 ed 7c cc d1 4a bb 28 7f f1 b4 16
    45 24 17 b4 31 2a 80 4f 37 ff 2a 17 c8 1f 12 b5
    95 a4 8b 30 11 d6
write to 0xcfc510 [0xd0b8a0] (75 bytes => 75 (0x4B))
0000 - 16 03 03 00 46 10 00 00-42 41 04 96 66 2b af 0c   ....F...BA..f+..
0010 - cf 33 f5 61 f7 c8 76 5c-bb dc ad e8 5e 4e 94 5e   .3.a..v\....^N.^
0020 - 5a 3e 0d 76 c1 48 25 7a-9e 47 ed 7c cc d1 4a bb   Z>.v.H%z.G.|..J.
0030 - 28 7f f1 b4 16 45 24 17-b4 31 2a 80 4f 37 ff 2a   (....E$..1*.O7.*
0040 - 17 c8 1f 12 b5 95 a4 8b-30 11 d6                  ........0..
SSL_connect:SSLv3 write client key exchange A
>>> ??? [length 0005]
    14 03 03 00 01
>>> TLS 1.2 ChangeCipherSpec [length 0001]
    01
write to 0xcfc510 [0xd0b8a0] (6 bytes => 6 (0x6))
0000 - 14 03 03 00 01 01                                 ......
SSL_connect:SSLv3 write change cipher spec A
>>> ??? [length 0005]
    16 03 03 00 28
>>> TLS 1.2 Handshake [length 0010], Finished
    14 00 00 0c 16 b1 6d 85 23 a7 a4 35 c7 33 14 24
write to 0xcfc510 [0xd0b8a0] (45 bytes => 45 (0x2D))
0000 - 16 03 03 00 28 96 40 e2-43 26 7d a3 a9 4b ac de   ....(.@.C&}..K..
0010 - 3d c5 36 32 b9 a8 21 0d-24 88 3c 8b 82 c0 6d c2   =.62..!.$.<...m.
0020 - 67 0f e2 96 fa b1 37 6f-4b 57 9c b6 82            g.....7oKW...
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data

@bnoordhuis
Copy link
Member

You have a few bugs in your 'newSession' handler. This:

server.on('newSession', function(id, data) {
    tlsSessionStore[id] = data;
});

Should be this:

server.on('newSession', function(id, data, cb) {
    tlsSessionStore[id] = data;
    cb();
});

Also, note that id is a buffer, not a string. It contains binary data so if you use it as a key in a dictionary, it's going to get toString-ed and that might end up clobbering it.

@silverwind
Copy link
Contributor

@Fr1ar sorry for linking that, I didn't realize it was outdated. I'll see if we can provide a working example in the docs soon.

@Fr1ar
Copy link
Author

Fr1ar commented Oct 1, 2015

@bnoordhuis, @silverwind Thanks guys! After I added the 'cb' parameter to the newSession function everything works fine!
Now my code looks like:

var tlsSessionStore = {};
server.on("newSession", function (id, data, cb) {
    tlsSessionStore[id.toString("hex")] = data;
    cb();
});
server.on("resumeSession", function (id, cb) {
    var tlsSessionId = id.toString("hex");
    cb(null, (tlsSessionId in tlsSessionStore) ? tlsSessionStore[tlsSessionId] : null);
});

@jbergstroem
Copy link
Member

Looks like we're sorted here. Closing.

silverwind added a commit to silverwind/node that referenced this issue Oct 6, 2015
Using TLS session resumption correctly is not obvious. This added
example code should help new users understand how to use it correctly.

Related issue: nodejs#3132
silverwind added a commit that referenced this issue Oct 7, 2015
Using TLS session resumption correctly is not obvious. This added
example code should help new users understand how to use it correctly.

Related issue: #3132
PR-URL: #3147
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
silverwind added a commit that referenced this issue Oct 8, 2015
Using TLS session resumption correctly is not obvious. This added
example code should help new users understand how to use it correctly.

Related issue: #3132
PR-URL: #3147
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issues that look for answers. tls Issues and PRs related to the tls subsystem.
Projects
None yet
Development

No branches or pull requests

4 participants