ssb-keyring v7.0.0
ssb-keyring
A persistence store for encryption keys for scuttlebutt. It's purpose is to make easy to answer box2 encryption/ decryption questions.
This module was extracted from ssb-tribes
Usage
const Keyring = require('ssb-keyring')
const ssbKeys = require('ssb-keys')
const keys = ssbKeys.generate()
Keyring(`/tmp/keyring-demo-${Date.now()}`, (err, keyring) => {
keyring.signing.add(keys.id, keys)
// ...
})API
This module is responsible for recording key details:
- persisting encryption keys (async)
- persisting various signing keys (async)
- persisting who has access to keys (async)
Overview (methods most people should use):
/* SETUP */
Keyring(dbPath, cb)
/* REGISTERING */
keyring.signing.add(keys.id, keys)
keyring.dm.add(myLeafFeedId, theirLeafFeedId, myDHKeys, theirDHKeys, cb)
keyring.group.add(groupId, keyInfo, cb)
/* QUERYING */
keyring.signing.get(keys.id)
keyring.dm.get(myLeafFeedId, theirLeafFeedId)
keyring.group.get(groupId)
keys.close(cb)All querying methods are synchronous, so that encryption / decryption never has to wait for IO to access keys.
All registering methods:
- synchronously return a boolean indicating whether the key is new
- all querying is done on an in-memory cache, which new items are added to
- allow a callback argument at the end if you want to know when the keyring database persisted the key
- the only asynchronous aspect is for persistence
Keyring(path, cb)
where
pathString to location your keys will be persisted to on diskcbfunction calls back with(err, keyring)(wherekeyringis the keyring API)- if
cbnot provided, function returns a Promise
- if
keyring.signing.add(ssbKeys, cb) => Boolean
Takes some signing keys ssbKeys (made by ssb-keys or similar), and adds them
as keys you can use for signing messages or other content.
ssbKeysObject containing ed25519 keysssbKeys.idString base64 encoded "ID" resembling the public partssbKeys.curveString name of the cryptographic elliptic curve usedssbKeys.publicString base64 encoded public part of the keypairssbKeys.privateString base64 encoded private part of the keypair
cbfunction callback with signature(err) => {}, called after persistence
Returns true if this ssbKeys is new (not yet in the database), or returns
false if it was already in the database.
keyring.signing.addNamed(name, ssbKeys, cb) => Boolean
Similar to keyring.signing.add, but uses a free-form name string to identify
the keys.
This name can be used in keyring.signing.get(name) to retrieve the keys.
keyring.signing.has(id) => Boolean
Returns true if the keyring has a signing key for id, and false otherwise.
keyring.signing.get(id) => Object | null
Returns the signing keys for id, or null if the keyring doesn't have any.
Alternatively, you can pass a name instead of id if you used
keyring.signing.addNamed.
keyring.dm.add(myId, theirId, myDHKeys, theirDHKeys, cb) => Boolean
Takes a pair of Diffie-Hellman keys myDHKeys and theirDHKeys (made with
ssb-private-group-keys), and their identifiers myId and theirId, then
performs Diffie-Hellman key exchange to derive a shared secret, and adds it to
the keyring.
myIdString identifier for the local peer, usually a feed SSB URItheirIdString identifier for the remote peer, usually a feed SSB URImyDHKeysDHKeys class instance (fromssb-private-group-keys)theirDHKeysDHKeys class instance (fromssb-private-group-keys)cbfunction callback with signature(err) => {}, called after persistence
Returns true if the shared secret is new (not yet in the database), or returns
false if it was already in the database.
keyring.dm.has(myId, theirId) => Boolean
Returns true if the keyring has a shared secret for the pair of myId and
theirId, and false otherwise.
keyring.dm.get(myId, theirId) => Object | null
Returns the shared secret for the Diffie-Hellman key exchange between myId and
theirId, or null if the keyring doesn't have any.
keyring.dm.addTriangle(xRootId, xLeafId, yLeafId, cb) => Boolean
Takes the identifiers for a "triangle" of feed IDs in two metafeed trees, and registers these in the keyring database.
xRootIdString identifier for the root feed of the first metafeed treexLeafIdString identifier for the leaf feed of the first metafeed treeyLeafIdString identifier for the leaf feed of the second metafeed treecbfunction callback with signature(err) => {}, called after persistence
Returns true if the triangle is new (not yet in the database), or returns
false if it was already in the database.
keyring.dm.triangulate(xRootId, yLeafId) => String | null
Returns xLeafId if the keyring has a triangle between xRootId and yLeafId.
keyring.self.set(keyInfo, cb)
Your keyring will always intialize and check if a self-key has been set. You can use this method to override that default.
keyInfoObject contains symmetric keyinfo.keyString base64 encoded symmetric keyinfo.schemestring (optional)
cbfunction callback with signature(err)
keyring.self.get() => keyInfo
Returns the keyInfo for the self-key.
keyring.group.add(groupId, addInfo, cb)
Adds a group key to the keyring, where
groupIdString a cloaked message Id which identifies the groupaddInfoObject:addInfo.keyBuffer - the group encryption key (needed ifaddInfo.schemeis set)addInfo.schemeString - scheme of that encryption key (optional, there is only one option at the moment which we default to)addInfo.rootMessageId the id of thegroup/initmessage (optional)
cbfunction callback with signature(err) => {}called after persistence
Can be called multiple times to add more read keys. The first time you add a key it will be automatically picked as the write key. If you call group.add with addInfo.key on an excluded group, the group will automatically be un-excluded.
`keyring.group.pickWriteKey(groupId, pickedKey, cb)
Allows you to pick one of the group's current readKeys and promote it to being the current writeKey that will be available in the object returned by keyring.group.get. pickedKey needs to exactly match one of the readKeys.
pickedKeyObject:pickedKey.keyBuffer - a group encryption keypickedKey.schemeString - scheme of that encryption key
cbfunction callback with signature(err) => {}called after persistence
keyring.group.has(groupId) => Boolean
Returns true if the keyring has a group key for groupId, and false otherwise, if you haven't been in the group or if you've been excluded.
keyring.group.get(groupId) => groupInfo
Returns the groupInfo that you've added with keyring.group.add for groupId, or null if the keyring doesn't have any. It has the format
groupInfo*Object`:groupInfo.writeKeyGroupKey the currently selected key for writing. Is always one ofgroupInfo.readKeys.groupInfo.readKeysArray\<GroupKey> all keys that you've added to thisgroupIdgroupInfo.rootMessageId the id of thegroup/initmessage.
where
groupKeyObject:groupKey.keyBuffer - a group encryption keygroupKey.schemeString - scheme of that encryption key
keyring.group.getUpdates(groupId) => PullStream<groupInfo>
Like keyring.group.get but instead as a live pull stream, that outputs whenever there's been a change to that group's info.
Note, this includes all "old" updates and then continues to emit new updates.
keyring.group.exclude(groupId, cb)
Marks group you've been in as excluded and removes its writeKey. This is useful if you or someone else excludes you from a group. The group info will lose the writeKey field and get an excluded field set to true.
keyring.group.list({ live, excluded }) => PullStream<groupId>
Returns an pull stream of all the groupIds in the keyring.
If live is true then it outputs all existing group ids but also all new ones added.
If excluded is true (default false) then it only returns excluded groups instead of only non-excluded groups.
keyring.group.listSync({ excluded }) => [groupId]
Returns an array of all the groupIds in the keyring
If excluded is true (default false) then it only returns excluded groups instead of only non-excluded groups.
keyring.poBox.add(poBoxId, info, cb)
where
poBoxIdString is an SSB-URI for a P.O. BoxinfoObjectinfo.keyBuffer - the private part of a diffie-hellman keyinfo.schemeString the scheme associated with that key (currently optional)
keyring.poBox.has(poBoxId) => Boolean
keyring.poBox.get(poBoxId) => keyInfo
keyring.poBox.list(poBoxId) => [poBoxId]
keys.close(cb)
Closes the keyring database
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago