2016-05-20 21:29:53 +02:00
|
|
|
'use strict'
|
|
|
|
|
2016-05-22 13:19:17 +02:00
|
|
|
const duplexify = require('duplexify')
|
|
|
|
const lpstream = require('length-prefixed-stream')
|
|
|
|
|
2016-05-22 01:51:15 +02:00
|
|
|
const handshake = require('./handshake')
|
|
|
|
|
2016-05-22 13:19:17 +02:00
|
|
|
exports.SecureSession = class SecureSession {
|
2016-05-22 01:51:15 +02:00
|
|
|
constructor (local, key, insecure) {
|
|
|
|
this.localKey = key
|
|
|
|
this.localPeer = local
|
|
|
|
this.sharedSecret = null
|
|
|
|
this.local = {}
|
|
|
|
this.remote = {}
|
2016-05-22 18:36:31 +02:00
|
|
|
this.proposal = {}
|
2016-05-22 01:51:15 +02:00
|
|
|
this.insecure = insecure
|
2016-05-22 22:39:36 +02:00
|
|
|
this.secure = null
|
2016-05-22 13:19:17 +02:00
|
|
|
const e = lpstream.encode()
|
|
|
|
const d = lpstream.decode()
|
|
|
|
this.insecureLp = duplexify(e, d)
|
|
|
|
|
|
|
|
e.pipe(this.insecure)
|
|
|
|
this.insecure.pipe(d)
|
2016-05-22 01:51:15 +02:00
|
|
|
|
|
|
|
if (!this.localPeer) {
|
|
|
|
throw new Error('no local id provided')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.localKey) {
|
|
|
|
throw new Error('no local private key provided')
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enable when implemented in js-peer-id
|
|
|
|
// if (!this.localPeer.matchesPrivateKey(this.localKey)) {
|
|
|
|
// throw new Error('peer.ID does not match privateKey')
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (!insecure) {
|
|
|
|
throw new Error('no insecure stream provided')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-22 22:39:36 +02:00
|
|
|
secureStream (cb) {
|
|
|
|
this.handshake((err) => {
|
|
|
|
if (err) return cb(err)
|
|
|
|
|
|
|
|
cb(null, this.secure)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-05-22 18:36:31 +02:00
|
|
|
handshake (cb) {
|
2016-05-22 01:51:15 +02:00
|
|
|
// TODO: figure out how to best handle the handshake timeout
|
2016-05-22 18:36:31 +02:00
|
|
|
if (this._handshakeLock) {
|
|
|
|
return cb(new Error('handshake already in progress'))
|
|
|
|
}
|
|
|
|
|
2016-05-22 01:51:15 +02:00
|
|
|
this._handshakeLock = true
|
|
|
|
|
2016-05-22 18:36:31 +02:00
|
|
|
const finish = (err) => {
|
2016-05-22 01:51:15 +02:00
|
|
|
this._handshakeLock = false
|
2016-05-22 18:36:31 +02:00
|
|
|
cb(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._handshakeDone) {
|
|
|
|
return finish()
|
2016-05-22 01:51:15 +02:00
|
|
|
}
|
|
|
|
|
2016-05-22 18:36:31 +02:00
|
|
|
handshake(this, (err) => {
|
|
|
|
if (err) {
|
|
|
|
return finish(err)
|
|
|
|
}
|
2016-05-22 01:51:15 +02:00
|
|
|
|
2016-05-22 18:36:31 +02:00
|
|
|
this._handshakeDone = true
|
|
|
|
finish()
|
|
|
|
})
|
2016-05-22 01:51:15 +02:00
|
|
|
}
|
|
|
|
}
|