Open TheBestOrNothing opened 3 years ago
If you set the environment variable NODE_DEBUG=tls
, you should get some debug logs for the TLS handshake. Also, it would probably help to modify the greeter client to output the error that the call ends with.
@murgatroid99 Thanks for your clue.
TLS 10914: client _init handle? true
TLS 10914: client initRead handle? true buffered? false
TLS 10914: client _start handle? true connecting? false requestOCSP? false
Error: 14 UNAVAILABLE: No connection established
.....
code: 14,
details: 'No connection established',
metadata: Metadata { internalRepr: Map(0) {}, options: {}
Server side:
openssl s_server -accept 20000 -cert server.cert -key server.key -debug -tlsextdebug -curves secp256k1 -tls1_2
Client side:
openssl s_client -showcerts -connect localhost:20000 -CAfile ca.cert -cert client.cert -key client.key -curves secp256k1 -tls1_2
At last, mutual auth handshake successfully with right CIPHER and both side communicate well.
CIPHER is ECDHE-ECDSA-AES256-GCM-SHA384
Supported Elliptic Groups: secp256k1
Shared Elliptic groups: secp256k1
Secure Renegotiation IS supported
Note: The parameter -curves secp256k1 -tls1_2 are key to pass auth.
OK, that cipher is in Node's default cipher suite and Node is supposed to automatically select the correct curve by default, so that part should work. The issue might be with the -tls1_2
option. Are you passing that because your certificate is incompatible with TLS v1.3? My quick testing shows that Node 14 sets a default minimum TLS version of 1.2 and a default maximum version of 1.3, so if the certificate is incompatible with TLS 1.3, that could be the problem.
@murgatroid99 It is failed to mutual auth with TLS 1.3 according to the issue. But I am not stop trying -) I have successfully created a node server and client with TLS 1.2. All the code can been found in the repository.
var tls = require('tls'),
fs = require('fs'),
msg = [
".-..-..-. .-. .-. .--. .---. .-. .---. .-.",
": :; :: : : :.-.: :: ,. :: .; :: : : . :: :",
": :: : : :: :: :: :: :: .': : : :: :: :",
": :: :: : : `' `' ;: :; :: :.`.: :__ : :; ::_;",
":_;:_;:_; `.,`.,' `.__.':_;:_;:___.':___.':_;"
].join("\n").cyan;
var options = { ca: fs.readFileSync('./credentials/ca.cert'), key: fs.readFileSync('./credentials/server.key'), cert: fs.readFileSync('./credentials/server.cert'), ecdhCurve: 'secp256k1', maxVersion: 'TLSv1.2', ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384' };
tls.createServer(options, function (s) { s.write(msg+"\n"); s.pipe(s); }).listen(8000);
3. Access server with client
var tls = require('tls'), fs = require('fs');
var options = { ca: fs.readFileSync('./credentials/ca.cert'), key: fs.readFileSync('./credentials/client.key'), cert: fs.readFileSync('./credentials/client.cert'), ecdhCurve: 'secp256k1', maxVersion: 'TLSv1.2', ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384' };
var conn = tls.connect(8000, 'localhost', options, function() { if (conn.authorized) { console.log("Connection authorized by a Certificate Authority."); } else { console.log("Connection not authorized: " + conn.authorizationError) } });
// Send a friendly message conn.write("I am the client sending you a message.");
conn.on("data", function (data) { console.log('Receive:' + data.toString()); conn.end(); });
conn.on('close', function() { console.log("Connection closed"); });
conn.on('error', function(error) { console.error(error); conn.destroy(); });
4. Try it out
./gen.sh node server.js //in one shell node client.js //in anther shell
5. Output of client
Connection authorized by a Certificate Authority. Receive:undefined Receive:I am the client sending you a message. Connection closed
The server and client handshake successfully with dedicated ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384'.
So as to grpc node, could we assign the TLS options (showed in the server and client code) to grpc node?
That cipher is in the default cipher suite. Did you try without explicitly setting the ciphers
? And it's supposed to automatically choose the curve. Did you try without explicitly setting the ecdhCurve
option?
Also, the responses on the issue you linked say that TLSv3 intentionally does not support that cipher because it is obsolete. Maybe you'd be better off just using a cipher that is still supported.
That cipher is in the default cipher suite. Did you try without explicitly setting the ciphers? And it's supposed to automatically choose the curve. Did you try without explicitly setting the ecdhCurve option?
It is OK without explicitly setting the ecdhCurve option. Server and client works well without assigning the ciphers ECDHE-ECDSA-AES256-GCM-SHA384.
Also, the responses on the issue you linked say that TLSv3 intentionally does not support that cipher because it is obsolete. Maybe you'd be better off just using a cipher that is still supported.
The reason is secp256k1 is not recommended in TLSv3, not referenced in RFC 8446, and defined in RFC 8422. Here is detailed discription. In TLS Supported Groups, the secp256k1 is not recommended -(
Problem description
I've been using a self generated RSA Certificate Authority to sign my server and clients certificates and so far grpc node mutual authentication worked fine.
Following the same why, I'm trying to use secp256k1 with the ECDSA algorithm, assmuming that the key of BTC or ETH will be used grpc authentication directly. Unfortunately I cannot get right output.
Reproduction steps
All the following contents and steps can been found from the repository
echo "CA's self-signed certificate" openssl x509 -in ca.cert -noout -text
2. Generate web server's private key and certificate signing request (EC)
openssl ecparam -genkey -out server.key -name secp256k1 openssl req -key server.key -new -out server.req -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/emailAddress=server@gmail.com"
3. Use CA's private key to sign web server's CSR and get back the signed certificate
openssl x509 -req -in server.req -days 60 -CA ca.cert -CAkey ca.key -CAcreateserial -out server.cert -extfile server.ext
echo "Server's signed certificate" openssl x509 -in server.cert -noout -text
4. Generate client's private key and certificate signing request (EC)
openssl ecparam -genkey -out client.key -name secp256k1 openssl req -key client.key -new -out client.req -subj "/C=FR/ST=Alsace/L=Strasbourg/O=PC Client/OU=Computer/CN=*.client.com/emailAddress=client@gmail.com"
5. Use CA's private key to sign client's CSR and get back the signed certificate
openssl x509 -req -in client.req -days 60 -CA ca.cert -CAkey ca.key -CAcreateserial -out client.cert -extfile client.ext
echo "Client's signed certificate" openssl x509 -in client.cert -noout -text
6. To verify the server certificate aginst by root CA
echo "server's certificate verification" openssl verify -show_chain -CAfile ca.cert server.cert
7. To verify the client certificate aginst by root CA.
echo "client's certificate verification" openssl verify -show_chain -CAfile ca.cert client.cert
function main() { var server = new grpc.Server();
server.addService(hello_proto.Greeter.service, {sayHello: sayHello}); server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createSsl( fs.readFileSync('./credentials/ca.cert'), [{ cert_chain: fs.readFileSync('./credentials/server.cert'), private_key: fs.readFileSync('./credentials/server.key') }], true ), () => { server.start(); }); }
var client = new hello_proto.Greeter(target, grpc.credentials.createSsl(fs.readFileSync('./credentials/ca.cert'), fs.readFileSync('./credentials/client.key'), fs.readFileSync('./credentials/client.cert')));
TypeError: Cannot read property 'message' of undefined at Object.callback (grpc-auth-secp256k1/greeter_client.js:57:39) at Object.onReceiveStatus (grpc-auth-secp256k1/node_modules/@grpc/grpc-js/build/src/client.js:176:36) at Object.onReceiveStatus (grpc-auth-secp256k1/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:342:141) at Object.onReceiveStatus OpenssLabs/grpc-auth-secp256k1/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:305:181) at grpc-auth-secp256k1/node_modules/@grpc/grpc-js/build/src/call-stream.js:124:78 at processTicksAndRejections (internal/process/task_queues.js:75:11)