Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

PeerId objects not properly supported as argument to options.init privateKey entry #2261

Closed
carsonfarmer opened this issue Jul 16, 2019 · 10 comments
Assignees
Labels
exp/novice Someone with a little familiarity can pick up help wanted Seeking public contribution on this issue kind/bug A bug in existing code (including security flaws) P3 Low: Not priority right now status/ready Ready to be worked

Comments

@carsonfarmer
Copy link

carsonfarmer commented Jul 16, 2019

Version: { version: '0.36.4', repo: 7, commit: '' }
Platform: Darwin carson.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
Subsystem: new IPFS({}), based on libp2p/js-peer-id

This should work (in Typescript):

const peerId = await create({ bits: 256, keyType: 'ed25519' })
const node = new IPFS({
  init: {
    privateKey: peerId,
  }
})

Here's a simpler pure JS version:

const IPFS = require('ipfs');
const PeerId = require('peer-id');

PeerId.create().then(peerId => {
  const node = new IPFS({
    init: {
      privateKey: peerId
    }
  })
})

However, I keep seeing TypeError: Expected a value of type boolean | {bits,emptyRepo,privateKey,pass} | undefined for init but received {"privateKey":{"id":"blah","privKey":"blah","pubKey":"blah"}}. The 'fix' (thanks to @Stebalien) is to do something like:

const peerId = await create({ bits: 256, keyType: 'ed25519' })
const privateKey = Object.assign({}, peerId) // Convert to object

I ended up needing the toB58String method on PeerId (see alternative below), as this is expected in ipfs/src/core/components/init.js:92:26

hence the alternative (which also seems to work):

const privateKey = peerId.toJSON()
privateKey.toB58String = peerId.toB58String

Then, using privateKey in our IPFS init call works nicely.

This seems to be associated with the superstruct definition. In fact, it seems there is a comment alluding to this fact in there: https://github.com/ipfs/js-ipfs/blob/master/src/core/config.js#L38.

So the 'fix' here is either, support things other than objects in options, or document that a 'raw' PeerId doesn't quite work here?

Happy to provide additional examples if needed.

@alanshaw
Copy link
Member

I think we just need to add a PeerId "type" to superstruct like we have with Multiaddr:

multiaddr: v => {

Would you be willing to send a PR?

@alanshaw alanshaw added kind/bug A bug in existing code (including security flaws) exp/novice Someone with a little familiarity can pick up help wanted Seeking public contribution on this issue P3 Low: Not priority right now status/ready Ready to be worked labels Jul 16, 2019
@carsonfarmer
Copy link
Author

Yup, willing and able 👍

@carsonfarmer
Copy link
Author

I'm not particularly familiar with superstruct though, do you know if, since its a union type (peerid|string) we'd need to create a 'custom' peerid-string type? I can dig into superstruct a bit if you don't know off-hand.

@alanshaw
Copy link
Member

alanshaw commented Aug 1, 2019

I imagined the PeerId "type" would validate a PeerId as either an instance of the class OR a string peer ID.

@jacobheun jacobheun self-assigned this May 28, 2020
@jacobheun
Copy link
Contributor

I believe this should be supported now, assigning myself to check.

@jacobheun
Copy link
Contributor

This is fixed, I was able to create and start a new node with this code:

const PeerId = require('peer-id')
const IPFS = require('ipfs')

;(async function() {
  const peerId = await PeerId.create({ bits: 256, keyType: 'ed25519' })
  const node = await IPFS.create({
    init: {
      privateKey: peerId,
    }
  })

  await node.start()
  await node.stop()
})()

@domwoe
Copy link

domwoe commented Jun 2, 2020

@jacobheun I'm trying the same, but my init object is not taken into account. It does not matter what peer id I feed to init, my node always has the same id. Probably as defined somewhere in ~/.jsipfs

@jacobheun
Copy link
Contributor

@domwoe if you already have an initialized repo (~/.jsipfs is not empty) your existing key will always be used. You should be able to check the existing key in the ~/.jsipfs/config file.

@DougAnderson444
Copy link
Contributor

DougAnderson444 commented Jun 3, 2020

@jacobheun I think this issue should remain open until libp2p-keychain supports keys other than RSA.

libp2p-keychain does not appear to be working with ed25519 keys. As soon as you try to use the ipfs node above created with an ed25519 key, you get a keychain pirvateKey.export error

//fails
      try {
        keysList = await node.key.list();
        console.log(keylist);
      } catch (err) {
        console.log(err);
      }

TypeError: privateKey.export is not a function at Keychain.importPeer (keychain.js:432)

https://github.com/libp2p/js-libp2p-keychain/blob/9e96dbc50f19b4f3912216f973e36be0d7d3596d/src/keychain.js#L432

KeyChain import/export is still tightly designed to RSA keys, and fails with any other key.

We need to be able to import/export non-RSA keys to the keychain

libp2p/js-libp2p-crypto#145

@jacobheun
Copy link
Contributor

The ed25519 key issue is being tracked at #2553, it's high on our list to get resolved.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
exp/novice Someone with a little familiarity can pick up help wanted Seeking public contribution on this issue kind/bug A bug in existing code (including security flaws) P3 Low: Not priority right now status/ready Ready to be worked
Projects
None yet
Development

No branches or pull requests

5 participants