84 lines
2.1 KiB
JavaScript
Raw Normal View History

2016-05-22 01:03:53 +02:00
'use strict'
const crypto = require('libp2p-crypto')
const debug = require('debug')
2016-05-22 01:33:50 +02:00
const fs = require('fs')
const path = require('path')
2016-05-22 13:19:17 +02:00
const protobuf = require('protocol-buffers')
2016-05-22 01:33:50 +02:00
2016-05-22 01:03:53 +02:00
const log = debug('libp2p:secio:handshake')
log.error = debug('libp2p:secio:handshake:error')
2016-05-22 01:33:50 +02:00
const pbm = protobuf(fs.readFileSync(path.join(__dirname, '../secio.proto')))
2016-05-22 01:31:00 +02:00
const support = require('../support')
2016-05-22 01:03:53 +02:00
module.exports = function exchange (session) {
log('2. exchange - start')
const eResult = crypto.generateEphemeralKeyPair(session.local.curveT)
session.local.ephemeralPubKey = eResult.key
const genSharedKey = eResult.genSharedKey
// Gather corpus to sign.
const selectionOut = Buffer.concat([
proposeOutBytes,
proposeInBytes,
session.local.ephemeralPubKey
])
const exchangeOut = pbm.Exchange({
epubkey: session.local.ephemeralPubKey,
signature: session.localKey.sign(selectionOut)
})
// TODO: write exchangeOut
// TODO: read exchangeIn
log('2.1. verify')
session.remote.ephemeralPubKey = exchangeIn.epubkey
const selectionIn = Buffer.concat([
proposeInBytes,
proposeOutBytes,
session.remote.ephemeralPubKey
])
const sigOk = session.remote.permanentPubKey.verify(selectionIn, exchangeIn.signature)
if (!sigOk) {
throw new Error('Bad signature')
}
log('2.1. verify - signature verified')
log('2.2. keys')
session.sharedSecret = genSharedKey(exchangeIn.epubkey)
const keys = crypto.keyStretcher(session.local.cipherT, session.local.hashT, session.sharedSecret)
// use random nonces to decide order.
if (order > 0) {
session.local.keys = keys.k1
session.remote.keys = keys.k2
} else if (order < 0) {
// swap
session.local.keys = keys.k2
session.remote.keys = keys.k1
} else {
// we should've bailed before this. but if not, bail here.
throw new Error('you are trying to talk to yourself')
}
log('2.2. keys - shared: %s\n\tlocal: %s\n\tremote: %s', session.sharedSecret, session.local.keys, session.remote.keys)
log('2.3. mac + cipher')
2016-05-22 01:31:00 +02:00
support.makeMacAndCipher(session.local)
support.makeMacAndCipher(session.remote)
2016-05-22 01:03:53 +02:00
log('2. exchange - finish')
}