Skip to content

Commit 2c357a7

Browse files
committed
tls: add getProtocol() to TLS sockets
This commit adds a new method for TLS sockets that returns the negotiated protocol version. PR-URL: #4995 Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 4501a28 commit 2c357a7

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

doc/api/tls.markdown

+18
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,24 @@ Example:
494494
If the peer does not provide a certificate, it returns `null` or an empty
495495
object.
496496

497+
### tlsSocket.getProtocol()
498+
499+
Returns a string containing the negotiated SSL/TLS protocol version of the
500+
current connection. `'unknown'` will be returned for connected sockets that have
501+
not completed the handshaking process. `null` will be returned for server
502+
sockets or disconnected client sockets.
503+
504+
Examples:
505+
```
506+
'SSLv3'
507+
'TLSv1'
508+
'TLSv1.1'
509+
'TLSv1.2'
510+
'unknown'
511+
```
512+
513+
See https://www.openssl.org/docs/manmaster/ssl/SSL_get_version.html for more
514+
information.
497515

498516
### tlsSocket.getSession()
499517

lib/_tls_wrap.js

+7
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,13 @@ TLSSocket.prototype.getEphemeralKeyInfo = function() {
649649
return null;
650650
};
651651

652+
TLSSocket.prototype.getProtocol = function() {
653+
if (this._handle)
654+
return this._handle.getProtocol();
655+
656+
return null;
657+
};
658+
652659
// TODO: support anonymous (nocert) and PSK
653660

654661

src/node_crypto.cc

+10
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
11921192
env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
11931193
env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
11941194
env->SetProtoMethod(t, "getEphemeralKeyInfo", GetEphemeralKeyInfo);
1195+
env->SetProtoMethod(t, "getProtocol", GetProtocol);
11951196

11961197
#ifdef SSL_set_max_send_fragment
11971198
env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
@@ -1954,6 +1955,15 @@ void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
19541955
}
19551956

19561957

1958+
template <class Base>
1959+
void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) {
1960+
Base* w = Unwrap<Base>(args.Holder());
1961+
1962+
const char* tls_version = SSL_get_version(w->ssl_);
1963+
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), tls_version));
1964+
}
1965+
1966+
19571967
#ifdef OPENSSL_NPN_NEGOTIATED
19581968
template <class Base>
19591969
int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,

src/node_crypto.h

+1
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ class SSLWrap {
248248
static void RequestOCSP(const v8::FunctionCallbackInfo<v8::Value>& args);
249249
static void GetEphemeralKeyInfo(
250250
const v8::FunctionCallbackInfo<v8::Value>& args);
251+
static void GetProtocol(const v8::FunctionCallbackInfo<v8::Value>& args);
251252

252253
#ifdef SSL_set_max_send_fragment
253254
static void SetMaxSendFragment(

test/parallel/test-tls-getprotocol.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
5+
if (!common.hasCrypto) {
6+
console.log('1..0 # Skipped: missing crypto');
7+
return;
8+
}
9+
10+
const tls = require('tls');
11+
const fs = require('fs');
12+
13+
const clientConfigs = [
14+
{ secureProtocol: 'TLSv1_method', version: 'TLSv1' },
15+
{ secureProtocol: 'TLSv1_1_method', version: 'TLSv1.1' },
16+
{ secureProtocol: 'TLSv1_2_method', version: 'TLSv1.2' }
17+
];
18+
19+
const serverConfig = {
20+
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
21+
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem')
22+
};
23+
24+
const server = tls.createServer(serverConfig, common.mustCall(function() {
25+
26+
}, clientConfigs.length)).listen(common.PORT, common.localhostIPv4, function() {
27+
let connected = 0;
28+
clientConfigs.forEach(function(v) {
29+
tls.connect({
30+
host: common.localhostIPv4,
31+
port: common.PORT,
32+
rejectUnauthorized: false,
33+
secureProtocol: v.secureProtocol
34+
}, common.mustCall(function() {
35+
assert.strictEqual(this.getProtocol(), v.version);
36+
this.on('end', common.mustCall(function() {
37+
assert.strictEqual(this.getProtocol(), null);
38+
})).end();
39+
if (++connected === clientConfigs.length)
40+
server.close();
41+
}));
42+
});
43+
});

0 commit comments

Comments
 (0)