In relation to this question, I am trying to start a TLS server in node.js to reflect the one I created in OpenSSL. I have tested the client and server using OpenSSL from the command line and they successfully make a connection. When I try to port the server to node.js (and still connect to it with an OpenSSL client), I receive a 'no shared cipher' error. I am wondering if there is something special I need to do when using the passphrase
option with tls.createServer()
Below are my successful OpenSSL commands for server and client respectively, note that the passphrase.txt file contains a single line that is the passphrase:
$ openssl s_server -accept 8888 -cert server.cert -key server.key -pass file:passphrase.txt -CAfile ca.cert
$ openssl s_client -connect 127.0.0.1:8888 -cert client.cert -key client.key -pass file:passphrase.txt -CAfile ca.cert
I can also make a successful connection if I specify a cipher for the client and/or server with the additional argument of -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256'
. I am using elliptic curve keys generated with openssl ecparam
and signed with a CA created using openssl ca
as discussed in my previous question.
The server code written in node.js looks like this:
var tls = require('tls');
var fs = require('fs');
var msg = '***********\n\nHello there secure client!\n\n***********';
var port = 8888;
var host = 'localhost';
var options = {
cert : fs.readFileSync('server.cert'),
key : fs.readFileSync('server.key'),
passphrase : (fs.readFileSync('passphrase.txt')).toString(),
ca : fs.readFileSync('ca.cert'),
// ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256',
// requestCert : true,
// rejectUnauthorized : true
};
tls.createServer(options, function(cleartextStream) {
if (cleartextStream.authorized) {
console.log('Server-side connection authorized by a Certificate Authority.');
} else {
// TODO this code does not appear to get executed even on failed connections
console.log('Server-side connection not authorized: ' + cleartextStream.authorizationError);
}
// send the server message to the client
cleartextStream.write(msg);
cleartextStream.setEncoding('utf8');
cleartextStream.pipe(cleartextStream);
}).listen(port, function() {
console.log('Server started on port: ' + port);
}).on('clientError', function(err){
console.log('A failed client connection attempt occurred.');
console.error(err);
console.log();
});
After calling the above code with node tlsServer.js
and attempting to connect with an OpenSSL client on the command line, I receive the following messages.
SERVER:
$ node tlsServer.js
Server started on port: 8888
<< client started here >>
A failed client connection attempt occurred.
[Error: 6396:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:openssl\ssl\s3_srvr.c:1132:
]
CLIENT:
$ openssl s_client -connect 127.0.0.1:8888 -cert client.cert -key client.key -pass file:passphrase.txt -CAfile ca.cert
CONNECTED(00000003)
2674688:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
I am using node v0.6.15. And the errors do not change when I uncomment the ciphers
, requestCert
, and rejectUnauthorized
in the options list sent to tls.createServer()
. I also have a node.js cersion of the client, and I get a socket hang up code ECONNRESET when I attempt to connect to the node server, and the following error when trying to connect to a OpenSSL server:
Connection to localhost:8888 could not be made.
[Error: 6968:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:openssl\ssl\s23_clnt.c:602:
]
Thanks in advance for your help and ideas!
If the passphrase is wrong, maybe. Try removing it.
However, no_shared_cipher is an error raised when the client can't agree on a cipher suit with the server . Try first removing the cipher suit restriction on the server and seeing what it negotiates to use to isolate the problem. If this works, then place one with the client and see what happens.
Also, can you check that node is using the same openssl library as the openssl command.