Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
quic: complete keylogging output
Browse files Browse the repository at this point in the history
PR-URL: #31
  • Loading branch information
jasnell committed Aug 19, 2019
1 parent 8ea3356 commit ce3eff2
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
3 changes: 2 additions & 1 deletion lib/internal/quic/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ function onSessionExtend(bidi, maxStreams) {
}

function onSessionKeylog(line) {
process.nextTick(emit.bind(this[owner_symbol], 'keylog', line));
this[owner_symbol].emit('keylog', line);
// process.nextTick(emit.bind(this[owner_symbol], 'keylog', line));
}

// Called when a new QuicStream is ready to use
Expand Down
51 changes: 51 additions & 0 deletions src/node_quic_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,54 @@ inline void MessageCB(
}
}

inline std::string ToHex(const uint8_t *s, size_t len) {
static constexpr char LOWER_XDIGITS[] = "0123456789abcdef";
std::string res;
res.resize(len * 2);
for (size_t i = 0; i < len; ++i) {
auto c = s[i];
res[i * 2] = LOWER_XDIGITS[c >> 4];
res[i * 2 + 1] = LOWER_XDIGITS[c & 0x0f];
}
return res;
}

inline void LogSecret(
SSL *ssl,
int name,
const unsigned char *secret,
size_t secretlen) {
if (auto keylog_cb = SSL_CTX_get_keylog_callback(SSL_get_SSL_CTX(ssl))) {
unsigned char crandom[32];
if (SSL_get_client_random(ssl, crandom, 32) != 32)
return;
std::string line;
switch (name) {
case SSL_KEY_CLIENT_EARLY_TRAFFIC:
line = "QUIC_CLIENT_EARLY_TRAFFIC_SECRET";
break;
case SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC:
line = "QUIC_CLIENT_HANDSHAKE_TRAFFIC_SECRET";
break;
case SSL_KEY_CLIENT_APPLICATION_TRAFFIC:
line = "QUIC_CLIENT_TRAFFIC_SECRET_0";
break;
case SSL_KEY_SERVER_HANDSHAKE_TRAFFIC:
line = "QUIC_SERVER_HANDSHAKE_TRAFFIC_SECRET";
break;
case SSL_KEY_SERVER_APPLICATION_TRAFFIC:
line = "QUIC_SERVER_TRAFFIC_SECRET_0";
break;
default:
return;
}
line += " " + ToHex(crandom, 32);
line += " " + ToHex(secret, secretlen);
keylog_cb(ssl, line.c_str());
}
}


// KeyCB provides a hook into the keying process of the TLS handshake,
// triggering registration of the keys associated with the TLS session.
inline int KeyCB(
Expand All @@ -906,6 +954,9 @@ inline int KeyCB(
void* arg) {
QuicSession* session = static_cast<QuicSession*>(arg);

// Output the secret to the keylog
LogSecret(ssl, name, secret, secretlen);

return session->OnKey(name, secret, secretlen) != 0 ? 0 : 1;
}

Expand Down
15 changes: 12 additions & 3 deletions test/parallel/test-quic-client-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,32 @@ const filedata = fs.readFileSync(__filename, { encoding: 'utf8' });
const { createSocket } = require('quic');

let client;
const server = createSocket({ type: 'udp4', port: 0 });
const server = createSocket({ type: 'udp4', port: 5678 });

const unidata = ['I wonder if it worked.', 'test'];
const kServerName = 'test';
const kALPN = 'zzz'; // ALPN can be overriden to whatever we want

const keylogFile = fs.createWriteStream('keys.log');

const kKeylogs = [
/QUIC_SERVER_HANDSHAKE_TRAFFIC_SECRET.*/,
/SERVER_HANDSHAKE_TRAFFIC_SECRET.*/,
/QUIC_CLIENT_HANDSHAKE_TRAFFIC_SECRET.*/,
/CLIENT_HANDSHAKE_TRAFFIC_SECRET.*/,
/QUIC_SERVER_TRAFFIC_SECRET_0.*/,
/EXPORTER_SECRET.*/,
/SERVER_TRAFFIC_SECRET_0.*/,
/CLIENT_TRAFFIC_SECRET_0.*/
/QUIC_CLIENT_TRAFFIC_SECRET_0.*/,
/CLIENT_TRAFFIC_SECRET_0.*/,
];


const countdown = new Countdown(2, () => {
debug('Countdown expired. Destroying sockets');
server.close();
client.close();
keylogFile.end();
});

server.listen({ key, cert, alpn: kALPN });
Expand All @@ -47,6 +55,7 @@ server.on('session', common.mustCall((session) => {

session.on('keylog', common.mustCall((line) => {
assert(kKeylogs.shift().test(line));
keylogFile.write(line);
}, kKeylogs.length));

session.on('secure', common.mustCall((servername, alpn, cipher) => {
Expand Down Expand Up @@ -86,7 +95,7 @@ server.on('session', common.mustCall((session) => {

server.on('ready', common.mustCall(() => {
debug('Server is listening on port %d', server.address.port);
client = createSocket({ type: 'udp4', port: 0 });
client = createSocket({ type: 'udp4', port: 5679 });
const req = client.connect({
type: 'udp4',
address: 'localhost',
Expand Down

0 comments on commit ce3eff2

Please sign in to comment.