2016-09-13 13:23:11 +02:00
|
|
|
'use strict'
|
|
|
|
|
2016-11-29 16:36:56 +01:00
|
|
|
const crypto = require('crypto')
|
|
|
|
const setImmediate = require('async/setImmediate')
|
2016-10-03 23:15:21 +11:00
|
|
|
|
2016-11-29 16:36:56 +01:00
|
|
|
const curves = {
|
|
|
|
'P-256': 'prime256v1',
|
|
|
|
'P-384': 'secp384r1',
|
|
|
|
'P-521': 'secp521r1'
|
|
|
|
}
|
2016-09-13 13:23:11 +02:00
|
|
|
|
|
|
|
exports.generateEphmeralKeyPair = function (curve, callback) {
|
2016-11-29 16:36:56 +01:00
|
|
|
if (!curves[curve]) {
|
|
|
|
return callback(new Error(`Unkown curve: ${curve}`))
|
|
|
|
}
|
|
|
|
const ecdh = crypto.createECDH(curves[curve])
|
|
|
|
ecdh.generateKeys()
|
|
|
|
|
|
|
|
setImmediate(() => callback(null, {
|
|
|
|
key: ecdh.getPublicKey(),
|
|
|
|
genSharedKey (theirPub, forcePrivate, cb) {
|
2016-09-13 13:23:11 +02:00
|
|
|
if (typeof forcePrivate === 'function') {
|
|
|
|
cb = forcePrivate
|
2016-11-29 16:36:56 +01:00
|
|
|
forcePrivate = null
|
2016-09-13 13:23:11 +02:00
|
|
|
}
|
|
|
|
|
2016-11-29 16:36:56 +01:00
|
|
|
if (forcePrivate) {
|
|
|
|
ecdh.setPrivateKey(forcePrivate.private)
|
2016-09-13 13:23:11 +02:00
|
|
|
}
|
2016-10-03 23:15:21 +11:00
|
|
|
|
2016-11-29 16:36:56 +01:00
|
|
|
let secret
|
|
|
|
try {
|
|
|
|
secret = ecdh.computeSecret(theirPub)
|
|
|
|
} catch (err) {
|
|
|
|
return cb(err)
|
|
|
|
}
|
2016-10-03 23:15:21 +11:00
|
|
|
|
2016-11-29 16:36:56 +01:00
|
|
|
setImmediate(() => cb(null, secret))
|
|
|
|
}
|
|
|
|
}))
|
2016-10-03 23:15:21 +11:00
|
|
|
}
|