npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ssb-keyring

v7.0.0

Published

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

Downloads

689

Readme

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

  • path String to location your keys will be persisted to on disk
  • cb function calls back with (err, keyring) (where keyring is the keyring API)
    • if cb not provided, function returns a Promise

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.

  • ssbKeys Object containing ed25519 keys
    • ssbKeys.id String base64 encoded "ID" resembling the public part
    • ssbKeys.curve String name of the cryptographic elliptic curve used
    • ssbKeys.public String base64 encoded public part of the keypair
    • ssbKeys.private String base64 encoded private part of the keypair
  • cb function 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.

  • myId String identifier for the local peer, usually a feed SSB URI
  • theirId String identifier for the remote peer, usually a feed SSB URI
  • myDHKeys DHKeys class instance (from ssb-private-group-keys)
  • theirDHKeys DHKeys class instance (from ssb-private-group-keys)
  • cb function 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.

  • xRootId String identifier for the root feed of the first metafeed tree
  • xLeafId String identifier for the leaf feed of the first metafeed tree
  • yLeafId String identifier for the leaf feed of the second metafeed tree
  • cb function 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.

  • keyInfo Object contains symmetric key
    • info.key String base64 encoded symmetric key
    • info.scheme string (optional)
  • cb function 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

  • groupId String a cloaked message Id which identifies the group
  • addInfo Object:
    • addInfo.key Buffer - the group encryption key (needed if addInfo.scheme is set)
    • addInfo.scheme String - scheme of that encryption key (optional, there is only one option at the moment which we default to)
    • addInfo.root MessageId the id of the group/init message (optional)
  • cb function 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.

  • pickedKey Object:
    • pickedKey.key Buffer - a group encryption key
    • pickedKey.scheme String - scheme of that encryption key
  • cb function 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.writeKey GroupKey the currently selected key for writing. Is always one of groupInfo.readKeys.
    • groupInfo.readKeys Array<GroupKey> all keys that you've added to this groupId
    • groupInfo.root MessageId the id of the group/init message.

where

  • groupKey Object:
    • groupKey.key Buffer - a group encryption key
    • groupKey.scheme String - 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

  • poBoxId String is an SSB-URI for a P.O. Box
  • info Object
    • info.key Buffer - the private part of a diffie-hellman key
    • info.scheme String 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