mirror of
https://github.com/fluencelabs/js-peer-id
synced 2025-06-27 08:51:49 +00:00
Async Crypto Endeavour (#33)
* refactor: make import and creation async - This allows the use of native key generation in the browser BREAKING CHANGE: This changes the interface of .create, .createFromPrivKey, .createFromPubKey, .createFromJSON
This commit is contained in:
committed by
David Dias
parent
e08907ff94
commit
31701e236d
@ -4,4 +4,10 @@
|
||||
|
||||
const PeerId = require('./index.js')
|
||||
|
||||
console.log(JSON.stringify(PeerId.create().toJSON(), null, ' '))
|
||||
PeerId.create((err, id) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(id.toJSON(), null, 2))
|
||||
})
|
||||
|
119
src/index.js
119
src/index.js
@ -7,28 +7,25 @@
|
||||
const mh = require('multihashes')
|
||||
const crypto = require('libp2p-crypto')
|
||||
const assert = require('assert')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
class PeerId {
|
||||
constructor (id, privKey, pubKey) {
|
||||
assert(Buffer.isBuffer(id), 'invalid id provided')
|
||||
|
||||
if (pubKey) {
|
||||
assert(id.equals(pubKey.hash()), 'inconsistent arguments')
|
||||
}
|
||||
|
||||
if (privKey) {
|
||||
assert(id.equals(privKey.public.hash()), 'inconsistent arguments')
|
||||
}
|
||||
|
||||
if (privKey && pubKey) {
|
||||
assert(privKey.public.bytes.equals(pubKey.bytes), 'inconsistent arguments')
|
||||
}
|
||||
|
||||
this.id = id
|
||||
this.privKey = privKey
|
||||
this._privKey = privKey
|
||||
this._pubKey = pubKey
|
||||
}
|
||||
|
||||
get privKey () {
|
||||
return this._privKey
|
||||
}
|
||||
|
||||
get pubKey () {
|
||||
if (this._pubKey) {
|
||||
return this._pubKey
|
||||
@ -88,13 +85,26 @@ exports = module.exports = PeerId
|
||||
exports.Buffer = Buffer
|
||||
|
||||
// generation
|
||||
exports.create = function (opts) {
|
||||
exports.create = function (opts, callback) {
|
||||
if (typeof opts === 'function') {
|
||||
callback = opts
|
||||
opts = {}
|
||||
}
|
||||
opts = opts || {}
|
||||
opts.bits = opts.bits || 2048
|
||||
|
||||
const privKey = crypto.generateKeyPair('RSA', opts.bits)
|
||||
waterfall([
|
||||
(cb) => crypto.generateKeyPair('RSA', opts.bits, cb),
|
||||
(privKey, cb) => privKey.public.hash((err, digest) => {
|
||||
cb(err, digest, privKey)
|
||||
})
|
||||
], (err, digest, privKey) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
return new PeerId(privKey.public.hash(), privKey)
|
||||
callback(null, new PeerId(digest, privKey))
|
||||
})
|
||||
}
|
||||
|
||||
exports.createFromHexString = function (str) {
|
||||
@ -110,39 +120,94 @@ exports.createFromB58String = function (str) {
|
||||
}
|
||||
|
||||
// Public Key input will be a buffer
|
||||
exports.createFromPubKey = function (key) {
|
||||
exports.createFromPubKey = function (key, callback) {
|
||||
let buf = key
|
||||
if (typeof buf === 'string') {
|
||||
buf = new Buffer(key, 'base64')
|
||||
}
|
||||
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('callback is required')
|
||||
}
|
||||
|
||||
const pubKey = crypto.unmarshalPublicKey(buf)
|
||||
return new PeerId(pubKey.hash(), null, pubKey)
|
||||
pubKey.hash((err, digest) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
callback(null, new PeerId(digest, null, pubKey))
|
||||
})
|
||||
}
|
||||
|
||||
// Private key input will be a string
|
||||
exports.createFromPrivKey = function (key) {
|
||||
exports.createFromPrivKey = function (key, callback) {
|
||||
let buf = key
|
||||
if (typeof buf === 'string') {
|
||||
buf = new Buffer(key, 'base64')
|
||||
}
|
||||
|
||||
const privKey = crypto.unmarshalPrivateKey(buf)
|
||||
return new PeerId(privKey.public.hash(), privKey)
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('callback is required')
|
||||
}
|
||||
|
||||
waterfall([
|
||||
(cb) => crypto.unmarshalPrivateKey(buf, cb),
|
||||
(privKey, cb) => privKey.public.hash((err, digest) => {
|
||||
cb(err, digest, privKey)
|
||||
})
|
||||
], (err, digest, privKey) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
callback(null, new PeerId(digest, privKey))
|
||||
})
|
||||
}
|
||||
|
||||
exports.createFromJSON = function (obj) {
|
||||
let priv
|
||||
let pub
|
||||
|
||||
if (obj.privKey) {
|
||||
priv = crypto.unmarshalPrivateKey(new Buffer(obj.privKey, 'base64'))
|
||||
exports.createFromJSON = function (obj, callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('callback is required')
|
||||
}
|
||||
|
||||
if (obj.pubKey) {
|
||||
pub = crypto.unmarshalPublicKey(new Buffer(obj.pubKey, 'base64'))
|
||||
}
|
||||
const id = mh.fromB58String(obj.id)
|
||||
const rawPrivKey = obj.privKey && new Buffer(obj.privKey, 'base64')
|
||||
const rawPubKey = obj.pubKey && new Buffer(obj.pubKey, 'base64')
|
||||
const pub = rawPubKey && crypto.unmarshalPublicKey(rawPubKey)
|
||||
|
||||
return new PeerId(mh.fromB58String(obj.id), priv, pub)
|
||||
if (rawPrivKey) {
|
||||
waterfall([
|
||||
(cb) => crypto.unmarshalPrivateKey(rawPrivKey, cb),
|
||||
(priv, cb) => priv.public.hash((err, digest) => {
|
||||
cb(err, digest, priv)
|
||||
}),
|
||||
(privDigest, priv, cb) => {
|
||||
if (pub) {
|
||||
pub.hash((err, pubDigest) => {
|
||||
cb(err, privDigest, priv, pubDigest)
|
||||
})
|
||||
} else {
|
||||
cb(null, privDigest, priv)
|
||||
}
|
||||
}
|
||||
], (err, privDigest, priv, pubDigest) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
if (pub && !privDigest.equals(pubDigest)) {
|
||||
return callback(new Error('Public and private key do not match'))
|
||||
}
|
||||
|
||||
if (id && !privDigest.equals(id)) {
|
||||
return callback(new Error('Id and private key do not match'))
|
||||
}
|
||||
|
||||
callback(null, new PeerId(id, priv, pub))
|
||||
})
|
||||
} else {
|
||||
callback(null, new PeerId(id, null, pub))
|
||||
}
|
||||
}
|
||||
|
||||
function toB64Opt (val) {
|
||||
|
Reference in New Issue
Block a user