| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 49481d0 commit 0602166
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -584,6 +584,23 @@ if called on a server socket. The supported types are `'DH'` and `'ECDH'`. The | |||
| 584 | 584 | ||
| 585 | 585 | For Example: `{ type: 'ECDH', name: 'prime256v1', size: 256 }` | |
| 586 | 586 | ||
| 587 | + ### tlsSocket.getFinished() | ||
| 588 | + <!-- YAML | ||
| 589 | + added: REPLACEME | ||
| 590 | + --> | ||
| 591 | + | ||
| 592 | + * Returns: {Buffer|undefined} The latest `Finished` message that has been | ||
| 593 | + sent to the socket as part of a SSL/TLS handshake, or `undefined` if | ||
| 594 | + no `Finished` message has been sent yet. | ||
| 595 | + | ||
| 596 | + As the `Finished` messages are message digests of the complete handshake | ||
| 597 | + (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can | ||
| 598 | + be used for external authentication procedures when the authentication | ||
| 599 | + provided by SSL/TLS is not desired or is not enough. | ||
| 600 | + | ||
| 601 | + Corresponds to the `SSL_get_finished` routine in OpenSSL and may be used | ||
| 602 | + to implement the `tls-unique` channel binding from [RFC 5929][]. | ||
| 603 | + | ||
| 587 | 604 | ### tlsSocket.getPeerCertificate([detailed]) | |
| 588 | 605 | <!-- YAML | |
| 589 | 606 | added: v0.11.4 | |
@@ -627,6 +644,23 @@ For example: | |||
| 627 | 644 | ||
| 628 | 645 | If the peer does not provide a certificate, an empty object will be returned. | |
| 629 | 646 | ||
| 647 | + ### tlsSocket.getPeerFinished() | ||
| 648 | + <!-- YAML | ||
| 649 | + added: REPLACEME | ||
| 650 | + --> | ||
| 651 | + | ||
| 652 | + * Returns: {Buffer|undefined} The latest `Finished` message that is expected | ||
| 653 | + or has actually been received from the socket as part of a SSL/TLS handshake, | ||
| 654 | + or `undefined` if there is no `Finished` message so far. | ||
| 655 | + | ||
| 656 | + As the `Finished` messages are message digests of the complete handshake | ||
| 657 | + (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can | ||
| 658 | + be used for external authentication procedures when the authentication | ||
| 659 | + provided by SSL/TLS is not desired or is not enough. | ||
| 660 | + | ||
| 661 | + Corresponds to the `SSL_get_peer_finished` routine in OpenSSL and may be used | ||
| 662 | + to implement the `tls-unique` channel binding from [RFC 5929][]. | ||
| 663 | + | ||
| 630 | 664 | ### tlsSocket.getProtocol() | |
| 631 | 665 | <!-- YAML | |
| 632 | 666 | added: v5.7.0 | |
@@ -1369,3 +1403,4 @@ where `secure_socket` has the same API as `pair.cleartext`. | |||
| 1369 | 1403 | [specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html | |
| 1370 | 1404 | [tls.Server]: #tls_class_tls_server | |
| 1371 | 1405 | [`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback | |
| 1406 | + [RFC 5929]: https://tools.ietf.org/html/rfc5929 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -668,6 +668,16 @@ TLSSocket.prototype.getPeerCertificate = function(detailed) { | |||
| 668 | 668 | return null; | |
| 669 | 669 | }; | |
| 670 | 670 | ||
| 671 | + TLSSocket.prototype.getFinished = function() { | ||
| 672 | + if (this._handle) | ||
| 673 | + return this._handle.getFinished(); | ||
| 674 | + }; | ||
| 675 | + | ||
| 676 | + TLSSocket.prototype.getPeerFinished = function() { | ||
| 677 | + if (this._handle) | ||
| 678 | + return this._handle.getPeerFinished(); | ||
| 679 | + }; | ||
| 680 | + | ||
| 671 | 681 | TLSSocket.prototype.getSession = function() { | |
| 672 | 682 | if (this._handle) { | |
| 673 | 683 | return this._handle.getSession(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1615,6 +1615,8 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) { | |||
| 1615 | 1615 | HandleScope scope(env->isolate()); | |
| 1616 | 1616 | ||
| 1617 | 1617 | env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate); | |
| 1618 | + env->SetProtoMethod(t, "getFinished", GetFinished); | ||
| 1619 | + env->SetProtoMethod(t, "getPeerFinished", GetPeerFinished); | ||
| 1618 | 1620 | env->SetProtoMethod(t, "getSession", GetSession); | |
| 1619 | 1621 | env->SetProtoMethod(t, "setSession", SetSession); | |
| 1620 | 1622 | env->SetProtoMethod(t, "loadSession", LoadSession); | |
@@ -2133,6 +2135,52 @@ void SSLWrap<Base>::GetPeerCertificate( | |||
| 2133 | 2135 | } | |
| 2134 | 2136 | ||
| 2135 | 2137 | ||
| 2138 | + template <class Base> | ||
| 2139 | + void SSLWrap<Base>::GetFinished(const FunctionCallbackInfo<Value>& args) { | ||
| 2140 | + Environment* env = Environment::GetCurrent(args); | ||
| 2141 | + | ||
| 2142 | + Base* w; | ||
| 2143 | + ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); | ||
| 2144 | + | ||
| 2145 | + // We cannot just pass nullptr to SSL_get_finished() | ||
| 2146 | + // because it would further be propagated to memcpy(), | ||
| 2147 | + // where the standard requirements as described in ISO/IEC 9899:2011 | ||
| 2148 | + // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated. | ||
| 2149 | + // Thus, we use a dummy byte. | ||
| 2150 | + char dummy[1]; | ||
| 2151 | + size_t len = SSL_get_finished(w->ssl_, dummy, sizeof dummy); | ||
| 2152 | + if (len == 0) | ||
| 2153 | + return; | ||
| 2154 | + | ||
| 2155 | + char* buf = Malloc(len); | ||
| 2156 | + CHECK_EQ(len, SSL_get_finished(w->ssl_, buf, len)); | ||
| 2157 | + args.GetReturnValue().Set(Buffer::New(env, buf, len).ToLocalChecked()); | ||
| 2158 | + } | ||
| 2159 | + | ||
| 2160 | + | ||
| 2161 | + template <class Base> | ||
| 2162 | + void SSLWrap<Base>::GetPeerFinished(const FunctionCallbackInfo<Value>& args) { | ||
| 2163 | + Environment* env = Environment::GetCurrent(args); | ||
| 2164 | + | ||
| 2165 | + Base* w; | ||
| 2166 | + ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); | ||
| 2167 | + | ||
| 2168 | + // We cannot just pass nullptr to SSL_get_peer_finished() | ||
| 2169 | + // because it would further be propagated to memcpy(), | ||
| 2170 | + // where the standard requirements as described in ISO/IEC 9899:2011 | ||
| 2171 | + // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated. | ||
| 2172 | + // Thus, we use a dummy byte. | ||
| 2173 | + char dummy[1]; | ||
| 2174 | + size_t len = SSL_get_peer_finished(w->ssl_, dummy, sizeof dummy); | ||
| 2175 | + if (len == 0) | ||
| 2176 | + return; | ||
| 2177 | + | ||
| 2178 | + char* buf = Malloc(len); | ||
| 2179 | + CHECK_EQ(len, SSL_get_peer_finished(w->ssl_, buf, len)); | ||
| 2180 | + args.GetReturnValue().Set(Buffer::New(env, buf, len).ToLocalChecked()); | ||
| 2181 | + } | ||
| 2182 | + | ||
| 2183 | + | ||
| 2136 | 2184 | template <class Base> | |
| 2137 | 2185 | void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) { | |
| 2138 | 2186 | Environment* env = Environment::GetCurrent(args); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -269,6 +269,8 @@ class SSLWrap { | |||
| 269 | 269 | ||
| 270 | 270 | static void GetPeerCertificate( | |
| 271 | 271 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 272 | + static void GetFinished(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 273 | + static void GetPeerFinished(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 272 | 274 | static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 273 | 275 | static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 274 | 276 | static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,66 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const fixtures = require('../common/fixtures'); | ||
| 5 | + | ||
| 6 | + if (!common.hasCrypto) | ||
| 7 | + common.skip('missing crypto'); | ||
| 8 | + | ||
| 9 | + // This test ensures that tlsSocket.getFinished() and | ||
| 10 | + // tlsSocket.getPeerFinished() return undefined before | ||
| 11 | + // secure connection is established, and return non-empty | ||
| 12 | + // Buffer objects with Finished messages afterwards, also | ||
| 13 | + // verifying alice.getFinished() == bob.getPeerFinished() | ||
| 14 | + // and alice.getPeerFinished() == bob.getFinished(). | ||
| 15 | + | ||
| 16 | + const assert = require('assert'); | ||
| 17 | + const tls = require('tls'); | ||
| 18 | + | ||
| 19 | + const msg = {}; | ||
| 20 | + const pem = (n) => fixtures.readKey(`${n}.pem`); | ||
| 21 | + const server = tls.createServer({ | ||
| 22 | + key: pem('agent1-key'), | ||
| 23 | + cert: pem('agent1-cert') | ||
| 24 | + }, common.mustCall((alice) => { | ||
| 25 | + msg.server = { | ||
| 26 | + alice: alice.getFinished(), | ||
| 27 | + bob: alice.getPeerFinished() | ||
| 28 | + }; | ||
| 29 | + server.close(); | ||
| 30 | + })); | ||
| 31 | + | ||
| 32 | + server.listen(0, common.mustCall(() => { | ||
| 33 | + const bob = tls.connect({ | ||
| 34 | + port: server.address().port, | ||
| 35 | + rejectUnauthorized: false | ||
| 36 | + }, common.mustCall(() => { | ||
| 37 | + msg.client = { | ||
| 38 | + alice: bob.getPeerFinished(), | ||
| 39 | + bob: bob.getFinished() | ||
| 40 | + }; | ||
| 41 | + bob.end(); | ||
| 42 | + })); | ||
| 43 | + | ||
| 44 | + msg.before = { | ||
| 45 | + alice: bob.getPeerFinished(), | ||
| 46 | + bob: bob.getFinished() | ||
| 47 | + }; | ||
| 48 | + })); | ||
| 49 | + | ||
| 50 | + process.on('exit', () => { | ||
| 51 | + assert.strictEqual(undefined, msg.before.alice); | ||
| 52 | + assert.strictEqual(undefined, msg.before.bob); | ||
| 53 | + | ||
| 54 | + assert(Buffer.isBuffer(msg.server.alice)); | ||
| 55 | + assert(Buffer.isBuffer(msg.server.bob)); | ||
| 56 | + assert(Buffer.isBuffer(msg.client.alice)); | ||
| 57 | + assert(Buffer.isBuffer(msg.client.bob)); | ||
| 58 | + | ||
| 59 | + assert(msg.server.alice.length > 0); | ||
| 60 | + assert(msg.server.bob.length > 0); | ||
| 61 | + assert(msg.client.alice.length > 0); | ||
| 62 | + assert(msg.client.bob.length > 0); | ||
| 63 | + | ||
| 64 | + assert(msg.server.alice.equals(msg.client.alice)); | ||
| 65 | + assert(msg.server.bob.equals(msg.client.bob)); | ||
| 66 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments