Skip to content

Commit c3f8aab

Browse files
mscdexrvagg
authored andcommitted
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 b4db318 commit c3f8aab

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
@@ -664,6 +664,13 @@ TLSSocket.prototype.getEphemeralKeyInfo = function() {
664664
return null;
665665
};
666666

667+
TLSSocket.prototype.getProtocol = function() {
668+
if (this._handle)
669+
return this._handle.getProtocol();
670+
671+
return null;
672+
};
673+
667674
// TODO: support anonymous (nocert) and PSK
668675

669676

src/node_crypto.cc

+10
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
12031203
env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
12041204
env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
12051205
env->SetProtoMethod(t, "getEphemeralKeyInfo", GetEphemeralKeyInfo);
1206+
env->SetProtoMethod(t, "getProtocol", GetProtocol);
12061207

12071208
#ifdef SSL_set_max_send_fragment
12081209
env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
@@ -1965,6 +1966,15 @@ void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
19651966
}
19661967

19671968

1969+
template <class Base>
1970+
void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) {
1971+
Base* w = Unwrap<Base>(args.Holder());
1972+
1973+
const char* tls_version = SSL_get_version(w->ssl_);
1974+
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), tls_version));
1975+
}
1976+
1977+
19681978
#ifdef OPENSSL_NPN_NEGOTIATED
19691979
template <class Base>
19701980
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)