Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private cabals #93

Open
garbados opened this issue Jun 24, 2020 · 2 comments
Open

Private cabals #93

garbados opened this issue Jun 24, 2020 · 2 comments

Comments

@garbados
Copy link
Contributor

garbados commented Jun 24, 2020

Related to password-protected cabals, it should be possible to create a cabal that has:

  1. Protected entry (admin must approve or pre-approve peers, or challenge peers to provide a password, or both)
  2. Protected reads (messages must be encrypted using a shared key issued by admin)

Such a cabal must have at least one or more admins to be protected in this way. It is important to protect entry as obscurity is not privacy, and important to protect reads in case the multifeed falls into hostile hands.

For example, consider this hypothetical scenario:

  1. Peer creates a cabal and designates themselves as an admin. They enter or generate a challenge key -- a password -- and an encryption key. A sync-only key is also generated that can be used in place of the challenge key.
  2. Additional peer joins. They present the correct challenge key, and the admin passes them the encryption key as part of the handshake. (If the peer presented the sync-only key, the admin would NOT pass them the encryption key, but would begin sharing the multifeed. This enables sync-only peers, such as relays, without compromising the integrity of the cabal.)
  3. Admin publishes the message "hello friendo", which is written to the multifeed as:
{
  "type": "chat/encrypted",
  "content": "..."
}

The value of the content field can then be decrypted into a normal message:

{
  type: 'chat/text',
  content: {
    text: 'default',
    channel: 'hello friendo'
  }
}

In this way the encryption key is never written to the log itself.

  1. Peer loses control of their machine and a hostile entity recovers the multifeed, but they are unable to read it because the encryption key is only shared during the handshake.
  2. Attacker, undaunted, cracks the discovery key and the challenge key. They connect to the swarm and retrieve a list of peers, but are unable to access the multifeed because the admin manually rejects them during the handshake. All other peers, recognizing the admin, also reject the attacker peer.

The end result is a private, encrypted cabal using public hyperswarm infrastructure.

@garbados
Copy link
Contributor Author

garbados commented Jun 24, 2020

If a challenge key or encryption key becomes compromised but no peer has lost control of their machine, an admin should be able to rotate it, even if only through some formalized process of starting a new cabal. For example, an admin might execute code like this to regenerate a cabal with the same allow-list and settings, but with a new challenge and/or encryption key:

cabal.regenerate((err, newCabal) => { ... }) // default settings, regenerates challenge and encryption keys
cabal.regenerate({ challenge: false }, (err, newCabal) => { ... }) // generate new encryption key, keep challenge key

When an admin regenerates the cabal, they post a final message to the old cabal that allows peers to follow them:

{
  "type": "cabal/regenerate",
  "content": {
    "key": "${discoveryKey}"
  }
}

The new encryption key is shared during handshaking and so should not be included in this regeneration message. A compliant client could then automatically switch over to the new cabal, prompting the user for a new challenge key if it has been rotated.

@okdistribute
Copy link
Member

This is so awesome! Great job explaining it thoroughly as well. I can see this being immensely useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants