From 83e6380d8fdf0580f533930d05db074aae195d80 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Thu, 9 Apr 2020 15:33:15 +0200 Subject: [PATCH 01/13] Add basic session key logging --- src/constants.ts | 2 ++ src/logger.ts | 1 + src/noise.ts | 6 +++++- src/utils.ts | 26 +++++++++++++++++++++++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index d17e594..46d7aca 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ export const NOISE_MSG_MAX_LENGTH_BYTES = 65535; export const NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = NOISE_MSG_MAX_LENGTH_BYTES - 16; +export const DUMP_SESSION_KEYS = true; + diff --git a/src/logger.ts b/src/logger.ts index 150e061..ad693e1 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,2 +1,3 @@ import debug from "debug"; export const logger = debug('libp2p:noise'); +export const sessionKeyLogger = debug('libp2p:session') diff --git a/src/noise.ts b/src/noise.ts index 404d9a7..421e6ee 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -9,7 +9,7 @@ import {encode, decode} from 'it-length-prefixed'; import {XXHandshake} from "./handshake-xx"; import {IKHandshake} from "./handshake-ik"; import {XXFallbackHandshake} from "./handshake-xx-fallback"; -import {generateKeypair, getPayload} from "./utils"; +import {generateKeypair, getPayload, dumpSessionKeys} from "./utils"; import {uint16BEDecode, uint16BEEncode} from "./encoder"; import {decryptStream, encryptStream} from "./crypto"; import {bytes} from "./@types/basic"; @@ -83,6 +83,8 @@ export class Noise implements INoiseConnection { }); const conn = await this.createSecureConnection(wrappedConnection, handshake); + dumpSessionKeys(handshake.session.hs, localPeer.id, remotePeer.id); + return { conn, remotePeer: handshake.remotePeer, @@ -113,6 +115,8 @@ export class Noise implements INoiseConnection { }); const conn = await this.createSecureConnection(wrappedConnection, handshake); + dumpSessionKeys(handshake.session.hs, localPeer.id, remotePeer ? remotePeer.id : undefined); + return { conn, remotePeer: handshake.remotePeer diff --git a/src/utils.ts b/src/utils.ts index a4004f9..fa0fb55 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,8 +4,10 @@ import PeerId from "peer-id"; import * as crypto from 'libp2p-crypto'; import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; -import {Hkdf, INoisePayload} from "./@types/handshake"; +import {Hkdf, INoisePayload, HandshakeState} from "./@types/handshake"; import {pb} from "./proto/payload"; +import {sessionKeyLogger} from "./logger" +import {DUMP_SESSION_KEYS} from "./constants" const NoiseHandshakePayloadProto = pb.NoiseHandshakePayload; @@ -113,3 +115,25 @@ export function getHkdf(ck: bytes32, ikm: bytes): Hkdf { export function isValidPublicKey(pk: bytes): boolean { return x25519.publicKeyVerify(pk.slice(0, 32)); } + +export function dumpSessionKeys(hs: HandshakeState, localPeerId: Buffer, remotePeerId=Buffer.alloc(0)): void { + if(!DUMP_SESSION_KEYS){ + return; + } + + if(hs.e === undefined){ + hs.e = {privateKey: Buffer.alloc(0), publicKey: Buffer.alloc(0)} + } + + const log = ` + PEER_ID_LOCAL ${localPeerId.toString('hex')} + PEER_ID_REMOTE ${remotePeerId.toString('hex')} + LOCAL_STATIC_KEY ${hs.s.privateKey.toString('hex')} + LOCAL_EPHEMEREAL_KEY ${hs.e.privateKey.toString('hex')} + REMOTE_STATIC_KEY ${hs.rs.toString('hex')} + REMOTE_EPHEMEREAL_KEY ${hs.re.toString('hex')} + ENCRYPTION_KEY ${hs.ss.cs.k.toString('hex')} + ` + + sessionKeyLogger(log); +} From 1653ea340ec880618fb53c35c115e804a0ed1c79 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 10 Apr 2020 13:35:38 +0200 Subject: [PATCH 02/13] Log session keys when created --- src/handshake-ik.ts | 20 +++++++++++++++++++- src/handshake-xx-fallback.ts | 9 ++++++++- src/handshake-xx.ts | 19 ++++++++++++++++++- src/logger.ts | 15 +++++++++++++-- src/noise.ts | 6 +----- src/utils.ts | 24 +----------------------- 6 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/handshake-ik.ts b/src/handshake-ik.ts index 983cf2e..cba1d13 100644 --- a/src/handshake-ik.ts +++ b/src/handshake-ik.ts @@ -8,7 +8,7 @@ import {Buffer} from "buffer"; import {decode0, decode1, encode0, encode1} from "./encoder"; import {decodePayload, getPeerIdFromPayload, verifySignedPayload} from "./utils"; import {FailedIKError} from "./errors"; -import {logger} from "./logger"; +import {logger, sessionKeyLogger} from "./logger"; import PeerId from "peer-id"; export class IKHandshake implements IHandshake { @@ -45,11 +45,18 @@ export class IKHandshake implements IHandshake { } public async stage0(): Promise { + sessionKeyLogger(`LOCAL_STATIC_PUBLIC_KEY ${this.session.hs.s.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_STATIC_PRIVATE_KEY ${this.session.hs.s.privateKey.toString('hex')}`) + sessionKeyLogger(`REMOTE_STATIC_PUBLIC_KEY ${this.session.hs.rs.toString('hex')}`) if (this.isInitiator) { logger("IK Stage 0 - Initiator sending message..."); const messageBuffer = this.ik.sendMessage(this.session, this.payload); this.connection.writeLP(encode1(messageBuffer)); logger("IK Stage 0 - Initiator sent message."); + if(this.session.hs.e){ + sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) + } } else { logger("IK Stage 0 - Responder receiving message..."); const receivedMsg = await this.connection.readLP(); @@ -64,12 +71,14 @@ export class IKHandshake implements IHandshake { this.remotePeer = this.remotePeer || await getPeerIdFromPayload(decodedPayload); await verifySignedPayload(this.session.hs.rs, decodedPayload, this.remotePeer); logger("IK Stage 0 - Responder successfully verified payload!"); + sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) } catch (e) { logger("Responder breaking up with IK handshake in stage 0."); throw new FailedIKError(receivedMsg, `Error occurred while verifying initiator's signed payload: ${e.message}`); } } + sessionKeyLogger(`SYMMETRIC_CIPHER_STATE ${this.session.hs.ss.cs.n} ${this.session.hs.ss.cs.k.toString('hex')}`) } public async stage1(): Promise { @@ -87,6 +96,7 @@ export class IKHandshake implements IHandshake { this.remotePeer = this.remotePeer || await getPeerIdFromPayload(decodedPayload); await verifySignedPayload(receivedMessageBuffer.ns.slice(0, 32), decodedPayload, this.remotePeer); logger("IK Stage 1 - Initiator successfully verified payload!"); + sessionKeyLogger(`REMOTE_EPHEMERAL_KEY ${this.session.hs.re.toString('hex')}`) } catch (e) { logger("Initiator breaking up with IK handshake in stage 1."); throw new FailedIKError(receivedMsg, `Error occurred while verifying responder's signed payload: ${e.message}`); @@ -96,6 +106,14 @@ export class IKHandshake implements IHandshake { const messageBuffer = this.ik.sendMessage(this.session, this.payload); this.connection.writeLP(encode0(messageBuffer)); logger("IK Stage 1 - Responder sent message..."); + if(this.session.hs.e){ + sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) + } + } + if(this.session.cs1 && this.session.cs2){ + sessionKeyLogger(`CIPHER_STATE_1 ${this.session.cs1.n} ${this.session.cs1.k.toString('hex')}`) + sessionKeyLogger(`CIPHER_STATE_2 ${this.session.cs2.n} ${this.session.cs2.k.toString('hex')}`) } } diff --git a/src/handshake-xx-fallback.ts b/src/handshake-xx-fallback.ts index 6217bc5..ad7a23b 100644 --- a/src/handshake-xx-fallback.ts +++ b/src/handshake-xx-fallback.ts @@ -4,7 +4,7 @@ import {XX} from "./handshakes/xx"; import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; import {decodePayload, getPeerIdFromPayload, verifySignedPayload,} from "./utils"; -import {logger} from "./logger"; +import {logger, sessionKeyLogger} from "./logger"; import {WrappedConnection} from "./noise"; import {decode0, decode1} from "./encoder"; import PeerId from "peer-id"; @@ -35,6 +35,10 @@ export class XXFallbackHandshake extends XXHandshake { public async propose(): Promise { if (this.isInitiator) { this.xx.sendMessage(this.session, Buffer.alloc(0), this.ephemeralKeys); + if(this.session.hs.e){ + sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) + } logger("XX Fallback Stage 0 - Initialized state as the first message was sent by initiator."); } else { logger("XX Fallback Stage 0 - Responder decoding initial msg from IK."); @@ -48,6 +52,7 @@ export class XXFallbackHandshake extends XXHandshake { throw new Error("xx fallback stage 0 decryption validation fail"); } logger("XX Fallback Stage 0 - Responder used received message from IK."); + sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) } } @@ -60,6 +65,8 @@ export class XXFallbackHandshake extends XXHandshake { throw new Error("xx fallback stage 1 decryption validation fail"); } logger('XX Fallback Stage 1 - Initiator used received message from IK.'); + sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) + sessionKeyLogger(`REMOTE_STATIC_KEY ${this.session.hs.rs.toString('hex')}`) logger("Initiator going to check remote's signature..."); try { diff --git a/src/handshake-xx.ts b/src/handshake-xx.ts index 41360e5..0f7ebe3 100644 --- a/src/handshake-xx.ts +++ b/src/handshake-xx.ts @@ -10,7 +10,7 @@ import { getPeerIdFromPayload, verifySignedPayload, } from "./utils"; -import { logger } from "./logger"; +import { logger, sessionKeyLogger } from "./logger"; import {decode0, decode1, decode2, encode0, encode1, encode2} from "./encoder"; import { WrappedConnection } from "./noise"; import PeerId from "peer-id"; @@ -50,11 +50,17 @@ export class XXHandshake implements IHandshake { // stage 0 public async propose(): Promise { + sessionKeyLogger(`LOCAL_STATIC_PUBLIC_KEY ${this.session.hs.s.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_STATIC_PRIVATE_KEY ${this.session.hs.s.privateKey.toString('hex')}`) if (this.isInitiator) { logger("Stage 0 - Initiator starting to send first message."); const messageBuffer = this.xx.sendMessage(this.session, Buffer.alloc(0)); this.connection.writeLP(encode0(messageBuffer)); logger("Stage 0 - Initiator finished sending first message."); + if(this.session.hs.e){ + sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) + } } else { logger("Stage 0 - Responder waiting to receive first message..."); const receivedMessageBuffer = decode0((await this.connection.readLP()).slice()); @@ -63,6 +69,7 @@ export class XXHandshake implements IHandshake { throw new Error("xx handshake stage 0 validation fail"); } logger("Stage 0 - Responder received first message."); + sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) } } @@ -76,6 +83,8 @@ export class XXHandshake implements IHandshake { throw new Error("xx handshake stage 1 validation fail"); } logger('Stage 1 - Initiator received the message.'); + sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) + sessionKeyLogger(`REMOTE_STATIC_KEY ${this.session.hs.rs.toString('hex')}`) logger("Initiator going to check remote's signature..."); try { @@ -91,6 +100,10 @@ export class XXHandshake implements IHandshake { const messageBuffer = this.xx.sendMessage(this.session, this.payload); this.connection.writeLP(encode1(messageBuffer)); logger('Stage 1 - Responder sent the second handshake message with signed payload.') + if(this.session.hs.e){ + sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) + sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) + } } } @@ -118,6 +131,10 @@ export class XXHandshake implements IHandshake { throw new Error(`Error occurred while verifying signed payload: ${e.message}`); } } + if(this.session.cs1 && this.session.cs2){ + sessionKeyLogger(`CIPHER_STATE_1 ${this.session.cs1.n} ${this.session.cs1.k.toString('hex')}`) + sessionKeyLogger(`CIPHER_STATE_2 ${this.session.cs2.n} ${this.session.cs2.k.toString('hex')}`) + } } public encrypt(plaintext: bytes, session: NoiseSession): bytes { diff --git a/src/logger.ts b/src/logger.ts index ad693e1..5c563c2 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,3 +1,14 @@ import debug from "debug"; -export const logger = debug('libp2p:noise'); -export const sessionKeyLogger = debug('libp2p:session') +import {DUMP_SESSION_KEYS} from './constants'; + + +let keyLogger; +if(DUMP_SESSION_KEYS){ + keyLogger = debug('libp2p:session') +} +else{ + keyLogger = () => {} +} + +export const sessionKeyLogger = keyLogger; +export const logger = debug('libp2p:noise'); \ No newline at end of file diff --git a/src/noise.ts b/src/noise.ts index 421e6ee..404d9a7 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -9,7 +9,7 @@ import {encode, decode} from 'it-length-prefixed'; import {XXHandshake} from "./handshake-xx"; import {IKHandshake} from "./handshake-ik"; import {XXFallbackHandshake} from "./handshake-xx-fallback"; -import {generateKeypair, getPayload, dumpSessionKeys} from "./utils"; +import {generateKeypair, getPayload} from "./utils"; import {uint16BEDecode, uint16BEEncode} from "./encoder"; import {decryptStream, encryptStream} from "./crypto"; import {bytes} from "./@types/basic"; @@ -83,8 +83,6 @@ export class Noise implements INoiseConnection { }); const conn = await this.createSecureConnection(wrappedConnection, handshake); - dumpSessionKeys(handshake.session.hs, localPeer.id, remotePeer.id); - return { conn, remotePeer: handshake.remotePeer, @@ -115,8 +113,6 @@ export class Noise implements INoiseConnection { }); const conn = await this.createSecureConnection(wrappedConnection, handshake); - dumpSessionKeys(handshake.session.hs, localPeer.id, remotePeer ? remotePeer.id : undefined); - return { conn, remotePeer: handshake.remotePeer diff --git a/src/utils.ts b/src/utils.ts index fa0fb55..0301e96 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,7 +4,7 @@ import PeerId from "peer-id"; import * as crypto from 'libp2p-crypto'; import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; -import {Hkdf, INoisePayload, HandshakeState} from "./@types/handshake"; +import {Hkdf, INoisePayload} from "./@types/handshake"; import {pb} from "./proto/payload"; import {sessionKeyLogger} from "./logger" import {DUMP_SESSION_KEYS} from "./constants" @@ -115,25 +115,3 @@ export function getHkdf(ck: bytes32, ikm: bytes): Hkdf { export function isValidPublicKey(pk: bytes): boolean { return x25519.publicKeyVerify(pk.slice(0, 32)); } - -export function dumpSessionKeys(hs: HandshakeState, localPeerId: Buffer, remotePeerId=Buffer.alloc(0)): void { - if(!DUMP_SESSION_KEYS){ - return; - } - - if(hs.e === undefined){ - hs.e = {privateKey: Buffer.alloc(0), publicKey: Buffer.alloc(0)} - } - - const log = ` - PEER_ID_LOCAL ${localPeerId.toString('hex')} - PEER_ID_REMOTE ${remotePeerId.toString('hex')} - LOCAL_STATIC_KEY ${hs.s.privateKey.toString('hex')} - LOCAL_EPHEMEREAL_KEY ${hs.e.privateKey.toString('hex')} - REMOTE_STATIC_KEY ${hs.rs.toString('hex')} - REMOTE_EPHEMEREAL_KEY ${hs.re.toString('hex')} - ENCRYPTION_KEY ${hs.ss.cs.k.toString('hex')} - ` - - sessionKeyLogger(log); -} From c4212027d0355b17be2351b18c9dfc1bf914ec2b Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 10 Apr 2020 13:39:55 +0200 Subject: [PATCH 03/13] Remove unused imports --- src/constants.ts | 1 + src/utils.ts | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 46d7aca..cfb43a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,3 +3,4 @@ export const NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = NOISE_MSG_MAX_LENGTH_BYTES export const DUMP_SESSION_KEYS = true; + diff --git a/src/utils.ts b/src/utils.ts index 0301e96..f142714 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,8 +6,6 @@ import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; import {Hkdf, INoisePayload} from "./@types/handshake"; import {pb} from "./proto/payload"; -import {sessionKeyLogger} from "./logger" -import {DUMP_SESSION_KEYS} from "./constants" const NoiseHandshakePayloadProto = pb.NoiseHandshakePayload; @@ -49,7 +47,7 @@ export async function createHandshakePayload( }); return Buffer.from(NoiseHandshakePayloadProto.encode(payloadInit).finish()); -} +} export async function signPayload(peerId: PeerId, payload: bytes): Promise { From ba4931d7c69cd0b6f7c7fff8537fa368e16230a8 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 10 Apr 2020 13:45:19 +0200 Subject: [PATCH 04/13] Remove whitespace --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index f142714..a4004f9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -47,7 +47,7 @@ export async function createHandshakePayload( }); return Buffer.from(NoiseHandshakePayloadProto.encode(payloadInit).finish()); -} +} export async function signPayload(peerId: PeerId, payload: bytes): Promise { From 2da9d3da6a1f9ea677eedebddf7d1078bf3d03d7 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 10 Apr 2020 14:22:09 +0200 Subject: [PATCH 05/13] Fix lint issues --- src/logger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index 5c563c2..01b7cea 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -4,10 +4,10 @@ import {DUMP_SESSION_KEYS} from './constants'; let keyLogger; if(DUMP_SESSION_KEYS){ - keyLogger = debug('libp2p:session') + keyLogger = debug('libp2p:session') } else{ - keyLogger = () => {} + keyLogger = () => {} } export const sessionKeyLogger = keyLogger; From 493d2901a928d71d63e5c5fee817c4e30b2a45bf Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 10 Apr 2020 14:54:50 +0200 Subject: [PATCH 06/13] Set dump session keys to false --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index cfb43a0..e9a8ee6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,6 @@ export const NOISE_MSG_MAX_LENGTH_BYTES = 65535; export const NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = NOISE_MSG_MAX_LENGTH_BYTES - 16; -export const DUMP_SESSION_KEYS = true; +export const DUMP_SESSION_KEYS = false; From 61d5674af113bcb783f8039f3c08abc7de73a291 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Tue, 14 Apr 2020 15:10:48 +0200 Subject: [PATCH 07/13] Replace log statements with log functions --- src/handshake-ik.ts | 28 ++++++++---------------- src/handshake-xx-fallback.ts | 15 ++++++------- src/handshake-xx.ts | 27 ++++++++---------------- src/logger.ts | 41 ++++++++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/handshake-ik.ts b/src/handshake-ik.ts index cba1d13..d482053 100644 --- a/src/handshake-ik.ts +++ b/src/handshake-ik.ts @@ -8,7 +8,7 @@ import {Buffer} from "buffer"; import {decode0, decode1, encode0, encode1} from "./encoder"; import {decodePayload, getPeerIdFromPayload, verifySignedPayload} from "./utils"; import {FailedIKError} from "./errors"; -import {logger, sessionKeyLogger} from "./logger"; +import {logger, logLocalStaticKeys, logRemoteStaticKey, logLocalEphemeralKeys, logRemoteEphemeralKey, logSymmetricCipherState, logCipherState} from "./logger"; import PeerId from "peer-id"; export class IKHandshake implements IHandshake { @@ -45,18 +45,14 @@ export class IKHandshake implements IHandshake { } public async stage0(): Promise { - sessionKeyLogger(`LOCAL_STATIC_PUBLIC_KEY ${this.session.hs.s.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_STATIC_PRIVATE_KEY ${this.session.hs.s.privateKey.toString('hex')}`) - sessionKeyLogger(`REMOTE_STATIC_PUBLIC_KEY ${this.session.hs.rs.toString('hex')}`) + logLocalStaticKeys(this.session.hs.s) + logRemoteStaticKey(this.session.hs.re) if (this.isInitiator) { logger("IK Stage 0 - Initiator sending message..."); const messageBuffer = this.ik.sendMessage(this.session, this.payload); this.connection.writeLP(encode1(messageBuffer)); logger("IK Stage 0 - Initiator sent message."); - if(this.session.hs.e){ - sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) - } + logLocalEphemeralKeys(this.session.hs.e) } else { logger("IK Stage 0 - Responder receiving message..."); const receivedMsg = await this.connection.readLP(); @@ -71,14 +67,14 @@ export class IKHandshake implements IHandshake { this.remotePeer = this.remotePeer || await getPeerIdFromPayload(decodedPayload); await verifySignedPayload(this.session.hs.rs, decodedPayload, this.remotePeer); logger("IK Stage 0 - Responder successfully verified payload!"); - sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) } catch (e) { logger("Responder breaking up with IK handshake in stage 0."); throw new FailedIKError(receivedMsg, `Error occurred while verifying initiator's signed payload: ${e.message}`); } } - sessionKeyLogger(`SYMMETRIC_CIPHER_STATE ${this.session.hs.ss.cs.n} ${this.session.hs.ss.cs.k.toString('hex')}`) + logSymmetricCipherState(this.session.hs.ss) } public async stage1(): Promise { @@ -96,7 +92,7 @@ export class IKHandshake implements IHandshake { this.remotePeer = this.remotePeer || await getPeerIdFromPayload(decodedPayload); await verifySignedPayload(receivedMessageBuffer.ns.slice(0, 32), decodedPayload, this.remotePeer); logger("IK Stage 1 - Initiator successfully verified payload!"); - sessionKeyLogger(`REMOTE_EPHEMERAL_KEY ${this.session.hs.re.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) } catch (e) { logger("Initiator breaking up with IK handshake in stage 1."); throw new FailedIKError(receivedMsg, `Error occurred while verifying responder's signed payload: ${e.message}`); @@ -106,15 +102,9 @@ export class IKHandshake implements IHandshake { const messageBuffer = this.ik.sendMessage(this.session, this.payload); this.connection.writeLP(encode0(messageBuffer)); logger("IK Stage 1 - Responder sent message..."); - if(this.session.hs.e){ - sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) - } - } - if(this.session.cs1 && this.session.cs2){ - sessionKeyLogger(`CIPHER_STATE_1 ${this.session.cs1.n} ${this.session.cs1.k.toString('hex')}`) - sessionKeyLogger(`CIPHER_STATE_2 ${this.session.cs2.n} ${this.session.cs2.k.toString('hex')}`) + logLocalEphemeralKeys(this.session.hs.e) } + logCipherState(this.session) } public decrypt(ciphertext: bytes, session: NoiseSession): {plaintext: bytes; valid: boolean} { diff --git a/src/handshake-xx-fallback.ts b/src/handshake-xx-fallback.ts index ad7a23b..f56df5c 100644 --- a/src/handshake-xx-fallback.ts +++ b/src/handshake-xx-fallback.ts @@ -3,8 +3,8 @@ import {XXHandshake} from "./handshake-xx"; import {XX} from "./handshakes/xx"; import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; -import {decodePayload, getPeerIdFromPayload, verifySignedPayload,} from "./utils"; -import {logger, sessionKeyLogger} from "./logger"; +import {decodePayload, getPeerIdFromPayload, verifySignedPayload} from "./utils"; +import {logger, logLocalEphemeralKeys, logRemoteEphemeralKey, logRemoteStaticKey} from "./logger"; import {WrappedConnection} from "./noise"; import {decode0, decode1} from "./encoder"; import PeerId from "peer-id"; @@ -35,11 +35,8 @@ export class XXFallbackHandshake extends XXHandshake { public async propose(): Promise { if (this.isInitiator) { this.xx.sendMessage(this.session, Buffer.alloc(0), this.ephemeralKeys); - if(this.session.hs.e){ - sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) - } logger("XX Fallback Stage 0 - Initialized state as the first message was sent by initiator."); + logLocalEphemeralKeys(this.session.hs.e) } else { logger("XX Fallback Stage 0 - Responder decoding initial msg from IK."); const receivedMessageBuffer = decode0(this.initialMsg); @@ -52,7 +49,7 @@ export class XXFallbackHandshake extends XXHandshake { throw new Error("xx fallback stage 0 decryption validation fail"); } logger("XX Fallback Stage 0 - Responder used received message from IK."); - sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) } } @@ -65,8 +62,8 @@ export class XXFallbackHandshake extends XXHandshake { throw new Error("xx fallback stage 1 decryption validation fail"); } logger('XX Fallback Stage 1 - Initiator used received message from IK.'); - sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) - sessionKeyLogger(`REMOTE_STATIC_KEY ${this.session.hs.rs.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) + logRemoteStaticKey(this.session.hs.rs) logger("Initiator going to check remote's signature..."); try { diff --git a/src/handshake-xx.ts b/src/handshake-xx.ts index 0f7ebe3..20d0408 100644 --- a/src/handshake-xx.ts +++ b/src/handshake-xx.ts @@ -10,7 +10,7 @@ import { getPeerIdFromPayload, verifySignedPayload, } from "./utils"; -import { logger, sessionKeyLogger } from "./logger"; +import { logger, logLocalStaticKeys, logLocalEphemeralKeys, logRemoteEphemeralKey, logRemoteStaticKey, logCipherState, logSymmetricCipherState } from "./logger"; import {decode0, decode1, decode2, encode0, encode1, encode2} from "./encoder"; import { WrappedConnection } from "./noise"; import PeerId from "peer-id"; @@ -50,17 +50,13 @@ export class XXHandshake implements IHandshake { // stage 0 public async propose(): Promise { - sessionKeyLogger(`LOCAL_STATIC_PUBLIC_KEY ${this.session.hs.s.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_STATIC_PRIVATE_KEY ${this.session.hs.s.privateKey.toString('hex')}`) + logLocalStaticKeys(this.session.hs.s) if (this.isInitiator) { logger("Stage 0 - Initiator starting to send first message."); const messageBuffer = this.xx.sendMessage(this.session, Buffer.alloc(0)); this.connection.writeLP(encode0(messageBuffer)); logger("Stage 0 - Initiator finished sending first message."); - if(this.session.hs.e){ - sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) - } + logLocalEphemeralKeys(this.session.hs.e) } else { logger("Stage 0 - Responder waiting to receive first message..."); const receivedMessageBuffer = decode0((await this.connection.readLP()).slice()); @@ -69,7 +65,7 @@ export class XXHandshake implements IHandshake { throw new Error("xx handshake stage 0 validation fail"); } logger("Stage 0 - Responder received first message."); - sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) } } @@ -83,8 +79,8 @@ export class XXHandshake implements IHandshake { throw new Error("xx handshake stage 1 validation fail"); } logger('Stage 1 - Initiator received the message.'); - sessionKeyLogger(`REMOTE_EPHEMEREAL_KEY ${this.session.hs.re.toString('hex')}`) - sessionKeyLogger(`REMOTE_STATIC_KEY ${this.session.hs.rs.toString('hex')}`) + logRemoteEphemeralKey(this.session.hs.re) + logRemoteStaticKey(this.session.hs.rs) logger("Initiator going to check remote's signature..."); try { @@ -100,10 +96,7 @@ export class XXHandshake implements IHandshake { const messageBuffer = this.xx.sendMessage(this.session, this.payload); this.connection.writeLP(encode1(messageBuffer)); logger('Stage 1 - Responder sent the second handshake message with signed payload.') - if(this.session.hs.e){ - sessionKeyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${this.session.hs.e.publicKey.toString('hex')}`) - sessionKeyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${this.session.hs.e.privateKey.toString('hex')}`) - } + logLocalEphemeralKeys(this.session.hs.e) } } @@ -131,10 +124,8 @@ export class XXHandshake implements IHandshake { throw new Error(`Error occurred while verifying signed payload: ${e.message}`); } } - if(this.session.cs1 && this.session.cs2){ - sessionKeyLogger(`CIPHER_STATE_1 ${this.session.cs1.n} ${this.session.cs1.k.toString('hex')}`) - sessionKeyLogger(`CIPHER_STATE_2 ${this.session.cs2.n} ${this.session.cs2.k.toString('hex')}`) - } + logSymmetricCipherState(this.session.hs.ss) + logCipherState(this.session) } public encrypt(plaintext: bytes, session: NoiseSession): bytes { diff --git a/src/logger.ts b/src/logger.ts index 01b7cea..fe8197a 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,6 +1,7 @@ import debug from "debug"; import {DUMP_SESSION_KEYS} from './constants'; - +import { KeyPair } from "./@types/libp2p"; +import { NoiseSession, SymmetricState } from "./@types/handshake"; let keyLogger; if(DUMP_SESSION_KEYS){ @@ -10,5 +11,41 @@ else{ keyLogger = () => {} } -export const sessionKeyLogger = keyLogger; +export function logLocalStaticKeys(s: KeyPair): void { + keyLogger(`LOCAL_STATIC_PUBLIC_KEY ${s.publicKey.toString('hex')}`) + keyLogger(`LOCAL_STATIC_PRIVATE_KEY ${s.privateKey.toString('hex')}`) +} + +export function logLocalEphemeralKeys(e: KeyPair|undefined): void { + if(e){ + keyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${e.publicKey.toString('hex')}`) + keyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${e.privateKey.toString('hex')}`) + } + else{ + keyLogger('Missing local ephemeral keys.') + } +} + +export function logRemoteStaticKey(rs: Buffer): void { + keyLogger(`REMOTE_STATIC_PUBLIC_KEY ${rs.toString('hex')}`) +} + +export function logRemoteEphemeralKey(re: Buffer): void { + keyLogger(`REMOTE_EPHEMERAL_PUBLIC_KEY ${re.toString('hex')}`) +} + +export function logCipherState(session: NoiseSession): void { + if(session.cs1 && session.cs2){ + keyLogger(`CIPHER_STATE_1 ${session.cs1.n} ${session.cs1.k.toString('hex')}`) + keyLogger(`CIPHER_STATE_2 ${session.cs2.n} ${session.cs2.k.toString('hex')}`) + } + else{ + keyLogger('Missing cipher state.') + } +} + +export function logSymmetricCipherState(ss: SymmetricState): void { + keyLogger(`SYMMETRIC_CIPHER_STATE ${ss.cs.n} ${ss.cs.k.toString('hex')}`) +} + export const logger = debug('libp2p:noise'); \ No newline at end of file From 7f871295a09d260419e52266230fb0ab57d4b614 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 09:48:55 +0200 Subject: [PATCH 08/13] Lint multiline imports --- src/handshake-ik.ts | 9 ++++++++- src/handshake-xx.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/handshake-ik.ts b/src/handshake-ik.ts index d482053..b7de34f 100644 --- a/src/handshake-ik.ts +++ b/src/handshake-ik.ts @@ -8,7 +8,14 @@ import {Buffer} from "buffer"; import {decode0, decode1, encode0, encode1} from "./encoder"; import {decodePayload, getPeerIdFromPayload, verifySignedPayload} from "./utils"; import {FailedIKError} from "./errors"; -import {logger, logLocalStaticKeys, logRemoteStaticKey, logLocalEphemeralKeys, logRemoteEphemeralKey, logSymmetricCipherState, logCipherState} from "./logger"; +import { + logger, + logLocalStaticKeys, + logRemoteStaticKey, + logLocalEphemeralKeys, + logRemoteEphemeralKey, + logSymmetricCipherState, logCipherState +} from "./logger"; import PeerId from "peer-id"; export class IKHandshake implements IHandshake { diff --git a/src/handshake-xx.ts b/src/handshake-xx.ts index 20d0408..4563b7b 100644 --- a/src/handshake-xx.ts +++ b/src/handshake-xx.ts @@ -10,7 +10,15 @@ import { getPeerIdFromPayload, verifySignedPayload, } from "./utils"; -import { logger, logLocalStaticKeys, logLocalEphemeralKeys, logRemoteEphemeralKey, logRemoteStaticKey, logCipherState, logSymmetricCipherState } from "./logger"; +import { + logger, + logLocalStaticKeys, + logLocalEphemeralKeys, + logRemoteEphemeralKey, + logRemoteStaticKey, + logCipherState, + logSymmetricCipherState +} from "./logger"; import {decode0, decode1, decode2, encode0, encode1, encode2} from "./encoder"; import { WrappedConnection } from "./noise"; import PeerId from "peer-id"; From 369d4054da379181a49d6e0c7f0daa57e9aa5c87 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 10:06:41 +0200 Subject: [PATCH 09/13] Set DUMP_SESSION_KEYS as env variable --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index e9a8ee6..9b34786 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,6 @@ export const NOISE_MSG_MAX_LENGTH_BYTES = 65535; export const NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = NOISE_MSG_MAX_LENGTH_BYTES - 16; -export const DUMP_SESSION_KEYS = false; +export const DUMP_SESSION_KEYS = process.env.DUMP_SESSION_KEYS; From d35e2a85d96b08cd50c950f190702c11f93e4ff1 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 10:18:05 +0200 Subject: [PATCH 10/13] Reuse existing logger for session keys --- src/logger.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index fe8197a..6a6543b 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -3,11 +3,13 @@ import {DUMP_SESSION_KEYS} from './constants'; import { KeyPair } from "./@types/libp2p"; import { NoiseSession, SymmetricState } from "./@types/handshake"; +export const logger = debug('libp2p:noise'); + let keyLogger; if(DUMP_SESSION_KEYS){ - keyLogger = debug('libp2p:session') + keyLogger = logger } -else{ +else { keyLogger = () => {} } @@ -47,5 +49,3 @@ export function logCipherState(session: NoiseSession): void { export function logSymmetricCipherState(ss: SymmetricState): void { keyLogger(`SYMMETRIC_CIPHER_STATE ${ss.cs.n} ${ss.cs.k.toString('hex')}`) } - -export const logger = debug('libp2p:noise'); \ No newline at end of file From 045a4322e72f10912d4dfe22a984984aced62f33 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 10:22:13 +0200 Subject: [PATCH 11/13] Lint --- src/logger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logger.ts b/src/logger.ts index 6a6543b..c0edd39 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -7,7 +7,7 @@ export const logger = debug('libp2p:noise'); let keyLogger; if(DUMP_SESSION_KEYS){ - keyLogger = logger + keyLogger = logger } else { keyLogger = () => {} From f406bcfa6ddfb88c6c1923bacd9e5409f631b6a0 Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 12:41:12 +0200 Subject: [PATCH 12/13] Fix log remote static key --- src/handshake-ik.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handshake-ik.ts b/src/handshake-ik.ts index b7de34f..1c4d02b 100644 --- a/src/handshake-ik.ts +++ b/src/handshake-ik.ts @@ -53,7 +53,7 @@ export class IKHandshake implements IHandshake { public async stage0(): Promise { logLocalStaticKeys(this.session.hs.s) - logRemoteStaticKey(this.session.hs.re) + logRemoteStaticKey(this.session.hs.rs) if (this.isInitiator) { logger("IK Stage 0 - Initiator sending message..."); const messageBuffer = this.ik.sendMessage(this.session, this.payload); From 55b906cd026b81acb62c8696c64acbf6b90d63ce Mon Sep 17 00:00:00 2001 From: Matija Petrunic Date: Fri, 17 Apr 2020 12:52:54 +0200 Subject: [PATCH 13/13] Remove SymmetricState log --- src/handshake-ik.ts | 3 +-- src/handshake-xx.ts | 2 -- src/logger.ts | 4 ---- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/handshake-ik.ts b/src/handshake-ik.ts index 1c4d02b..e67c2c7 100644 --- a/src/handshake-ik.ts +++ b/src/handshake-ik.ts @@ -14,7 +14,7 @@ import { logRemoteStaticKey, logLocalEphemeralKeys, logRemoteEphemeralKey, - logSymmetricCipherState, logCipherState + logCipherState } from "./logger"; import PeerId from "peer-id"; @@ -81,7 +81,6 @@ export class IKHandshake implements IHandshake { throw new FailedIKError(receivedMsg, `Error occurred while verifying initiator's signed payload: ${e.message}`); } } - logSymmetricCipherState(this.session.hs.ss) } public async stage1(): Promise { diff --git a/src/handshake-xx.ts b/src/handshake-xx.ts index 4563b7b..bbcbab1 100644 --- a/src/handshake-xx.ts +++ b/src/handshake-xx.ts @@ -17,7 +17,6 @@ import { logRemoteEphemeralKey, logRemoteStaticKey, logCipherState, - logSymmetricCipherState } from "./logger"; import {decode0, decode1, decode2, encode0, encode1, encode2} from "./encoder"; import { WrappedConnection } from "./noise"; @@ -132,7 +131,6 @@ export class XXHandshake implements IHandshake { throw new Error(`Error occurred while verifying signed payload: ${e.message}`); } } - logSymmetricCipherState(this.session.hs.ss) logCipherState(this.session) } diff --git a/src/logger.ts b/src/logger.ts index c0edd39..5f7c026 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -45,7 +45,3 @@ export function logCipherState(session: NoiseSession): void { keyLogger('Missing cipher state.') } } - -export function logSymmetricCipherState(ss: SymmetricState): void { - keyLogger(`SYMMETRIC_CIPHER_STATE ${ss.cs.n} ${ss.cs.k.toString('hex')}`) -}