diff --git a/SPEC/KEY.md b/SPEC/KEY.md index e9172f1b..2cd78445 100644 --- a/SPEC/KEY.md +++ b/SPEC/KEY.md @@ -122,3 +122,58 @@ ipfs.key.rename( } ``` +#### `export` + +> Export a key in a PEM encoded password protected PKCS #8 + +##### `Go` **NYI** + +##### `JavaScript` - ipfs.key.export(name, password, [callback]) + +Where: +- `name` is the local name for the key +- `password` is the password to protect the key + +`callback` must follow `function (err, pem) {}` signature, where `err` is an Error if the operation was not successful. `pem` is the string representation of the key + +If no `callback` is passed, a promise is returned. + +**Example:** + +```JavaScript +ipfs.key.export('self', 'password', (err, pem) => console.log(pem)) + +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDTA/BgkqhkiG9w0BBQ0wMjAaBgkqhkiG9w0BBQwwDQQIpdO40RVyBwACAWQw +... +YA== +-----END ENCRYPTED PRIVATE KEY----- + +``` + +#### `import` + +> Import a PEM encoded password protected PKCS #8 key + +##### `Go` **NYI** + +##### `JavaScript` - ipfs.key.import(name, pem, password, [callback]) + +Where: +- `name` is a local name for the key +- `pem` is the PEM encoded key +- `password` is the password that protects the PEM key + +`callback` must follow `function (err, key) {}` signature, where `err` is an Error if the operation was not successful. `key` is an object that describes the new key. + +If no `callback` is passed, a promise is returned. + +**Example:** + +```JavaScript +ipfs.key.import('clone', 'password', (err, key) => console.log(key)) + +{ Name: 'clone', + Id: 'QmQRiays958UM7norGRQUG3tmrLq8pJdmJarwYSk2eLthQ' +} +``` diff --git a/src/key.js b/src/key.js index 4b175ffd..48daa2d7 100644 --- a/src/key.js +++ b/src/key.js @@ -16,6 +16,7 @@ module.exports = (common) => { ] const keys = [] let ipfs + let withGo before(function (done) { // CI takes longer to instantiate the daemon, so we need to increase the @@ -27,7 +28,11 @@ module.exports = (common) => { factory.spawnNode((err, node) => { expect(err).to.not.exist() ipfs = node - done() + ipfs.id((err, id) => { + expect(err).to.not.exist() + withGo = id.agentVersion.startsWith('go-ipfs') + done() + }) }) }) }) @@ -139,5 +144,48 @@ module.exports = (common) => { }) }) }) + + describe('exchange', () => { + let selfPem + let passwordPem = hat() + + it('exports', (done) => { + if (withGo) { + console.log('Not supported by go-ipfs yet') + return done() + } + ipfs.key.export('self', passwordPem, (err, pem) => { + expect(err).to.not.exist() + expect(pem).to.exist() + selfPem = pem + done() + }) + }) + + it('imports', (done) => { + if (withGo) { + console.log('Not supported by go-ipfs yet') + return done() + } + ipfs.key.import('clone', selfPem, passwordPem, (err, key) => { + expect(err).to.not.exist() + expect(key).to.exist() + expect(key).to.have.property('Name', 'clone') + expect(key).to.have.property('Id') + done() + }) + }) + + it('removes', (done) => { + if (withGo) { + console.log('Not supported by go-ipfs yet') + return done() + } + ipfs.key.rm('clone', (err) => { + expect(err).to.not.exist() + done() + }) + }) + }) }) }