UNPKG

ssb-keyring

Version:

A persistence store for encryption keys for scuttlebutt. It's purpose is to make easy to answer box2 encryption/ decryption questions.

137 lines (115 loc) 3.77 kB
const { keySchemes } = require('private-group-spec') const { toBuffer, isObject, isString, isBuffer } = require('../util') function isSSBKeys (obj) { if (!obj || typeof obj !== 'object') return false if (!obj.id || typeof obj.id !== 'string') return false if (!obj.curve || typeof obj.curve !== 'string') return false if (!obj.public || typeof obj.public !== 'string') return false if (!obj.private || typeof obj.private !== 'string') return false return true } const keyEncoding = { encode (buf) { if (typeof buf === 'string') return buf if (isBuffer(buf)) return buf.toString('base64') throw new Error(`expected type Buffer|String, got ${typeof buf}`) }, decode: toBuffer } const schemeEncoding = { encode (str) { switch (str) { case keySchemes.private_group: return 1 case keySchemes.feed_id_self: return 2 case keySchemes.po_box: return 3 case keySchemes.feed_id_dm: return 4 case keySchemes.feed_id_metafeed_dm: return 5 default: return str } }, decode (int) { switch (int) { case 1: return keySchemes.private_group case 2: return keySchemes.feed_id_self case 3: return keySchemes.po_box case 4: return keySchemes.feed_id_dm case 5: return keySchemes.feed_id_metafeed_dm default: { console.log('ssb-keyring info-encoding found unknown entry:', int, typeof int) return int } } } } module.exports = { encode (info) { if (isString(info)) return JSON.stringify(info) if (isObject(info)) { if (isSSBKeys(info)) return JSON.stringify(info) const output = { root: info.root } // encode keys if (info.key) output.key = keyEncoding.encode(info.key) if (info.public) output.public = keyEncoding.encode(info.public) if (info.secret) output.secret = keyEncoding.encode(info.secret) if (info.writeKey?.key) { output.writeKey = { key: keyEncoding.encode(info.writeKey.key), scheme: schemeEncoding.encode(info.writeKey.scheme) } } if (info.readKeys) { output.readKeys = info.readKeys.map(readKey => ({ key: keyEncoding.encode(readKey.key), scheme: schemeEncoding.encode(readKey.scheme) })) } if (info.scheme) output.scheme = schemeEncoding.encode(info.scheme) if (info.excluded) output.excluded = true return JSON.stringify(output) } throw new Error('unable to encode info') }, decode (str) { const info = JSON.parse(str) if (isSSBKeys(info)) return info // decode keys if (info.key) info.key = keyEncoding.decode(info.key) if (info.public) info.public = keyEncoding.decode(info.public) if (info.secret) info.secret = keyEncoding.decode(info.secret) if (info.writeKey?.key) { info.writeKey = { key: keyEncoding.decode(info.writeKey.key), scheme: schemeEncoding.decode(info.writeKey.scheme) } } if (info.readKeys) { info.readKeys = info.readKeys.map(readKey => ({ key: keyEncoding.decode(readKey.key), scheme: schemeEncoding.decode(readKey.scheme) })) } if (info.scheme) info.scheme = schemeEncoding.decode(info.scheme) // migrate from old to new group storage format if (info.key && info.scheme === keySchemes.private_group) { if (!info.writeKey) { info.writeKey = { key: info.key, scheme: info.scheme } } if (!info.readKeys) { info.readKeys = [ { key: info.key, scheme: info.scheme } ] } delete info.key delete info.scheme } return info }, buffer: false, type: 'keystore-info-encoding' }