Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Commit

Permalink
fix: fixes importing and exporting eliptic curve keys and adds tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertoElias committed Feb 20, 2019
1 parent 38780c1 commit cf90937
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"async": "^2.6.1",
"interface-datastore": "~0.6.0",
"libp2p-crypto": "~0.16.0",
"libp2p-crypto-secp256k1": "~0.2.3",
"merge-options": "^1.0.1",
"node-forge": "~0.7.6",
"pull-stream": "^3.6.8",
Expand Down
24 changes: 16 additions & 8 deletions src/keychain.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class Keychain {
if (err) return _error(callback, err)

if (type === 'ed25519' || type === 'secp256k1') {
const keypairMarshal = keypair.marshal()
const keypairMarshal = keypair.bytes
self._storeKey(name, kid, keypairMarshal, dsname, callback)
} else {
keypair.export(this._(), (err, pem) => {
Expand Down Expand Up @@ -365,11 +365,15 @@ class Keychain {
* If it's as an RSA key, include a password to export as a PEM encrypted PKCS #8 string
*
* @param {string} name - The local key name; must already exist.
* @param {string} password - The password
* @param {string} password - The password, for RSA keys (optional)
* @param {function(Error, string)} callback
* @returns {undefined}
*/
exportKey (name, password, callback) {
if (typeof password === 'function' && typeof callback === 'undefined') {
callback = password
password = undefined
}
if (!validateKeyName(name)) {
return _error(callback, `Invalid key name '${name}'`)
}
Expand All @@ -379,14 +383,14 @@ class Keychain {
if (err) {
return _error(callback, `Key '${name}' does not exist. ${err.message}`)
}
const encKey = res.toString()
if (password) {
const encKey = res.toString()
crypto.keys.import(encKey, this._(), (err, privateKey) => {
if (err) return _error(callback, err)
privateKey.export(password, callback)
})
} else {
crypto.keys.unmarshalPrivateKey(encKey, callback)
crypto.keys.unmarshalPrivateKey(res, callback)
}
})
}
Expand All @@ -397,18 +401,23 @@ class Keychain {
*
* @param {string} name - The local key name; must not already exist.
* @param {string} encKey - The encoded key. If it's an RSA key, it needs to be a PEM encoded PKCS #8 string
* @param {string} password - The password for RSA keys.
* @param {string} password - The password for RSA keys. (optional)
* @param {function(Error, KeyInfo)} callback
* @returns {undefined}
*/
importKey (name, encKey, password, callback) {
const self = this
if (typeof password === 'function' && typeof callback === 'undefined') {
callback = password
password = undefined
}
if (!validateKeyName(name) || name === 'self') {
return _error(callback, `Invalid key name '${name}'`)
}
if (!encKey) {
return _error(callback, 'The encoded key is required')
}

const dsname = DsName(name)
self.store.has(dsname, (err, exists) => {
if (err) return _error(callback, err)
Expand All @@ -426,10 +435,9 @@ class Keychain {
})
})
} else {
const privateKey = crypto.keys.marshalPrivateKey(encKey)
privateKey.id((err, kid) => {
encKey.id((err, kid) => {
if (err) return _error(callback, err)
self._storeKey(name, kid, encKey, dsname, callback)
self._storeKey(name, kid, encKey.bytes, dsname, callback)
})
}
})
Expand Down
44 changes: 43 additions & 1 deletion test/keychain.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module.exports = (datastore1, datastore2) => {
const keyName = 'tajné jméno'
const renamedKeyName = 'ชื่อลับ'
let keyInfo
let ecKeyInfo
let secpKeyInfo
let emptyKeystore
let ks

Expand Down Expand Up @@ -85,15 +87,17 @@ module.exports = (datastore1, datastore2) => {
ks.createKey(keyName + 'ed25519', 'ed25519', 2048, (err, info) => {
expect(err).to.not.exist()
expect(info).exist()
ecKeyInfo = info
done()
})
})

xit('can be an secp256k1 key', function (done) {
it('can be an secp256k1 key', function (done) {
this.timeout(50 * 1000)
ks.createKey(keyName + 'secp256k1', 'secp256k1', 2048, (err, info) => {
expect(err).to.not.exist()
expect(info).exist()
secpKeyInfo = info
done()
})
})
Expand Down Expand Up @@ -280,6 +284,8 @@ module.exports = (datastore1, datastore2) => {

describe('exported key', () => {
let pemKey
let ed25519Key
let secp256k1Key

it('is a PKCS #8 encrypted pem', (done) => {
ks.exportKey(keyName, 'password', (err, pem) => {
Expand All @@ -299,6 +305,42 @@ module.exports = (datastore1, datastore2) => {
})
})

it('can export ed25519 key', (done) => {
ks.exportKey(keyName + 'ed25519', (err, key) => {
expect(err).to.not.exist()
ed25519Key = key
expect(key).to.exist()
done()
})
})

it('ed25519 key can be imported', (done) => {
ks.importKey('imported-key-ed25199', ed25519Key, (err, key) => {
expect(err).to.not.exist()
expect(key.name).to.equal('imported-key-ed25199')
expect(key.id).to.equal(ecKeyInfo.id)
done()
})
})

it('can export secp256k1 key', (done) => {
ks.exportKey(keyName + 'secp256k1', (err, key) => {
expect(err).to.not.exist()
secp256k1Key = key
expect(key).to.exist()
done()
})
})

it('secp256k1 key can be imported', (done) => {
ks.importKey('imported-key-secp256k1', secp256k1Key, (err, key) => {
expect(err).to.not.exist()
expect(key.name).to.equal('imported-key-secp256k1')
expect(key.id).to.equal(secpKeyInfo.id)
done()
})
})

it('cannot be imported as an existing key name', (done) => {
ks.importKey(keyName, pemKey, 'password', (err, key) => {
expect(err).to.exist()
Expand Down

0 comments on commit cf90937

Please sign in to comment.