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); -}