| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9b7bde1 commit dbee78c
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -45,6 +45,31 @@ changes: | |||
| 45 | 45 | ||
| 46 | 46 | See [`Session Resumption`][] for information about TLS session reuse. | |
| 47 | 47 | ||
| 48 | + #### Event: `'keylog'` | ||
| 49 | + <!-- YAML | ||
| 50 | + added: REPLACEME | ||
| 51 | + --> | ||
| 52 | + | ||
| 53 | + * `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format. | ||
| 54 | + * `tlsSocket` {tls.TLSSocket} The `tls.TLSSocket` instance on which it was | ||
| 55 | + generated. | ||
| 56 | + | ||
| 57 | + The `keylog` event is emitted when key material is generated or received by a | ||
| 58 | + connection managed by this agent (typically before handshake has completed, but | ||
| 59 | + not necessarily). This keying material can be stored for debugging, as it | ||
| 60 | + allows captured TLS traffic to be decrypted. It may be emitted multiple times | ||
| 61 | + for each socket. | ||
| 62 | + | ||
| 63 | + A typical use case is to append received lines to a common text file, which is | ||
| 64 | + later used by software (such as Wireshark) to decrypt the traffic: | ||
| 65 | + | ||
| 66 | + ```js | ||
| 67 | + // ... | ||
| 68 | + https.globalAgent.on('keylog', (line, tlsSocket) => { | ||
| 69 | + fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 }); | ||
| 70 | + }); | ||
| 71 | + ``` | ||
| 72 | + | ||
| 48 | 73 | ## Class: `https.Server` | |
| 49 | 74 | <!-- YAML | |
| 50 | 75 | added: v0.3.4 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,7 @@ const net = require('net'); | |||
| 27 | 27 | const EventEmitter = require('events'); | |
| 28 | 28 | const debug = require('internal/util/debuglog').debuglog('http'); | |
| 29 | 29 | const { async_id_symbol } = require('internal/async_hooks').symbols; | |
| 30 | - | ||
| 30 | + const kOnKeylog = Symbol('onkeylog'); | ||
| 31 | 31 | // New Agent code. | |
| 32 | 32 | ||
| 33 | 33 | // The largest departure from the previous implementation is that | |
@@ -120,10 +120,29 @@ function Agent(options) { | |||
| 120 | 120 | } | |
| 121 | 121 | } | |
| 122 | 122 | }); | |
| 123 | + | ||
| 124 | + // Don't emit keylog events unless there is a listener for them. | ||
| 125 | + this.on('newListener', maybeEnableKeylog); | ||
| 123 | 126 | } | |
| 124 | 127 | Object.setPrototypeOf(Agent.prototype, EventEmitter.prototype); | |
| 125 | 128 | Object.setPrototypeOf(Agent, EventEmitter); | |
| 126 | 129 | ||
| 130 | + function maybeEnableKeylog(eventName) { | ||
| 131 | + if (eventName === 'keylog') { | ||
| 132 | + this.removeListener('newListener', maybeEnableKeylog); | ||
| 133 | + // Future sockets will listen on keylog at creation. | ||
| 134 | + const agent = this; | ||
| 135 | + this[kOnKeylog] = function onkeylog(keylog) { | ||
| 136 | + agent.emit('keylog', keylog, this); | ||
| 137 | + }; | ||
| 138 | + // Existing sockets will start listening on keylog now. | ||
| 139 | + const sockets = Object.values(this.sockets); | ||
| 140 | + for (let i = 0; i < sockets.length; i++) { | ||
| 141 | + sockets[i].on('keylog', this[kOnKeylog]); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + | ||
| 127 | 146 | Agent.defaultMaxSockets = Infinity; | |
| 128 | 147 | ||
| 129 | 148 | Agent.prototype.createConnection = net.createConnection; | |
@@ -297,6 +316,10 @@ function installListeners(agent, s, options) { | |||
| 297 | 316 | s.removeListener('agentRemove', onRemove); | |
| 298 | 317 | } | |
| 299 | 318 | s.on('agentRemove', onRemove); | |
| 319 | + | ||
| 320 | + if (agent[kOnKeylog]) { | ||
| 321 | + s.on('keylog', agent[kOnKeylog]); | ||
| 322 | + } | ||
| 300 | 323 | } | |
| 301 | 324 | ||
| 302 | 325 | Agent.prototype.removeSocket = function removeSocket(s, options) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,44 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + if (!common.hasCrypto) | ||
| 5 | + common.skip('missing crypto'); | ||
| 6 | + | ||
| 7 | + const assert = require('assert'); | ||
| 8 | + const https = require('https'); | ||
| 9 | + const fixtures = require('../common/fixtures'); | ||
| 10 | + | ||
| 11 | + const server = https.createServer({ | ||
| 12 | + key: fixtures.readKey('agent2-key.pem'), | ||
| 13 | + cert: fixtures.readKey('agent2-cert.pem'), | ||
| 14 | + // Amount of keylog events depends on negotiated protocol | ||
| 15 | + // version, so force a specific one: | ||
| 16 | + minVersion: 'TLSv1.3', | ||
| 17 | + maxVersion: 'TLSv1.3', | ||
| 18 | + }, (req, res) => { | ||
| 19 | + res.end('bye'); | ||
| 20 | + }).listen(() => { | ||
| 21 | + https.get({ | ||
| 22 | + port: server.address().port, | ||
| 23 | + rejectUnauthorized: false, | ||
| 24 | + }, (res) => { | ||
| 25 | + res.resume(); | ||
| 26 | + res.on('end', () => { | ||
| 27 | + // Trigger TLS connection reuse | ||
| 28 | + https.get({ | ||
| 29 | + port: server.address().port, | ||
| 30 | + rejectUnauthorized: false, | ||
| 31 | + }, (res) => { | ||
| 32 | + server.close(); | ||
| 33 | + res.resume(); | ||
| 34 | + }); | ||
| 35 | + }); | ||
| 36 | + }); | ||
| 37 | + }); | ||
| 38 | + | ||
| 39 | + const verifyKeylog = (line, tlsSocket) => { | ||
| 40 | + assert(Buffer.isBuffer(line)); | ||
| 41 | + assert.strictEqual(tlsSocket.encrypted, true); | ||
| 42 | + }; | ||
| 43 | + server.on('keylog', common.mustCall(verifyKeylog, 10)); | ||
| 44 | + https.globalAgent.on('keylog', common.mustCall(verifyKeylog, 10)); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,9 +21,13 @@ const server = tls.createServer({ | |||
| 21 | 21 | rejectUnauthorized: false, | |
| 22 | 22 | }); | |
| 23 | 23 | ||
| 24 | - const verifyBuffer = (line) => assert(Buffer.isBuffer(line)); | ||
| 25 | - server.on('keylog', common.mustCall(verifyBuffer, 5)); | ||
| 26 | - client.on('keylog', common.mustCall(verifyBuffer, 5)); | ||
| 24 | + server.on('keylog', common.mustCall((line, tlsSocket) => { | ||
| 25 | + assert(Buffer.isBuffer(line)); | ||
| 26 | + assert.strictEqual(tlsSocket.encrypted, true); | ||
| 27 | + }, 5)); | ||
| 28 | + client.on('keylog', common.mustCall((line) => { | ||
| 29 | + assert(Buffer.isBuffer(line)); | ||
| 30 | + }, 5)); | ||
| 27 | 31 | ||
| 28 | 32 | client.once('secureConnect', () => { | |
| 29 | 33 | server.close(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments