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

Add a share key to conceal read keys from a follower #38

Closed
sanderpick opened this issue Oct 22, 2019 · 11 comments
Closed

Add a share key to conceal read keys from a follower #38

sanderpick opened this issue Oct 22, 2019 · 11 comments
Assignees
Milestone

Comments

@sanderpick
Copy link
Member

sanderpick commented Oct 22, 2019

AddFollower should work like,

  • Get or create a symmetric share key for the thread (you will have it if you or anyone else has already added a follower). Store the key in the metadata store because it's for the whole thread.
  • Use this key to encrypt all log read keys before sending them to the follower.
  • Tag the key on to the thread address when sharing it.

Now, on the client,

  • Do NOT send the share key to the follower, just use it to decrypt the log read keys
@sanderpick sanderpick added this to the Sprint 22 milestone Oct 22, 2019
@sanderpick sanderpick self-assigned this Oct 22, 2019
@sanderpick sanderpick changed the title Add a share key for handling join links Add a share key to conceal read keys from a follower Oct 31, 2019
@sanderpick
Copy link
Member Author

^ Updated thinking in the issue description ... thoughts welcome!

@jsign
Copy link
Contributor

jsign commented Nov 1, 2019

First question is check if I'm on the same page on what the code currently does when AddFollower :

  • Push all logs we know to the follower
  • Adds the follower addr to our own log addr-book
  • Push our own log info (which now has the new follower as an addr), to other peers log writers of the thread

Where Push we mean sending log information, which currently contains all keys of the logs, addrs, and heads... not logic yet for only sending correct keys depending if sending things to followers or readers. Is this correct?

I feel I'm missing something. Since this is direct-talking with other peers, aren't channels assumed to be secure? Why do you need a shared key? (or maybe this is for external invites?).

@sanderpick
Copy link
Member Author

Yep, same page. The channels are secure but the crux here is ensuring that a follower can serve a thread (and all its logs and keys, including read keys) to new consumers without knowing the read key.

So, given a thread address like,

/ip4/x.x.x.x/tcp/4006/p2p/<peerID>/thread/<threadID>

Where the host is a follower, how can I get a hold of the read keys? The proposal above is to back-channel a key that was used to encrypt the log read keys in the address. Something like,

/ip4/x.x.x.x/tcp/4006/p2p/<peerID>/thread/<threadID>?key=xxx

Multiaddresses don't have query params like that but something to that effect. The client would parse out the key and NOT send it to the follower. It just uses it to decrypt the read keys on receipt.

@jsign
Copy link
Contributor

jsign commented Nov 1, 2019

Oh, that's more clear now.

Some thoughts/questions/claims to check:

  • So /ip4/x.x.x.x/tcp/4006/p2p/<peerID>/thread/<threadID>?key=xxx is sent over a secure-channel only between non-followers roles in the thread. Correct?
  • The LogInfo pushed to the follower would have the read key encrypted with key, correct?
  • If two-pair of peers do this protocol, they both would generate different keys since they never thought other keys before. How this fit with the concept of a unique key per thread? Is this uniqueness really necessary?

@sanderpick
Copy link
Member Author

sanderpick commented Nov 1, 2019

So /ip4/x.x.x.x/tcp/4006/p2p/<peerID>/thread/<threadID>?key=xxx is sent over a secure-channel only between non-followers roles in the thread. Correct?

Yep. For example, in an email, text, slack, other thread, etc. This is analogous to sharing a link to a google doc: "anyone with the link can read and write".

The LogInfo pushed to the follower would have the read key encrypted with key, correct?

Yep.

If two-pair of peers do this protocol, they both would generate different keys since they never thought other keys before. How this fit with the concept of a unique key per thread? Is this uniqueness really necessary?

I was thinking that the key could be passed around and used if it's present, such that I could serve an address to your follower:

  • Get or create a symmetric share key for the thread (you will have it if you or anyone else has already added a follower). Store the key in the metadata store because it's for the whole thread.

The key could be tied to the follower so that each follower has their own, but then a third peer that was already in the thread would not be able to pick up new logs from a follower since it wouldn't have the key used to encrypt its logs. Tricky to visualize without drawing it out. Ideally, all followers would host logs encrypted with the same key.

@jsign
Copy link
Contributor

jsign commented Nov 1, 2019

Definitely sounds good that key can be shared as you mention.

But even if that's the intention, I think it can't be avoided that some two peers generate new key unintentionally. What I'm imagining this could happen:

  • A thread with many peers with no existing followers for anyone. Two peers add new followers for them before receiving the other notice about a generated key. Result: two distinct _key_s exist, two different followers have encrypted data with different keys.
  • A less pessimistic scenario can be a non-updated writer comes online again and, for some reason, doesn't receive the push of a prior writer generated key. So, adding a follower would generate a new key.

To be clear, I think is optimal to re-use key if one is known. But I think this multiple keys situation can't be avoided, and not really clear about how to handle it... since readers should have a way to realize if the key they're assuming to be true for decryption is the correct one. (I can imagine solutions, but that'd add some extra metadata (e.g: hash of the key or something similar)).

@sanderpick
Copy link
Member Author

The key could be created when the thread is created, and then always shared with the address when adding new peers. In a sense, this would be like using a keypair for the thread (like the logs), where peers all have the private key and followers only have the public key except we have the benefit of better encryption and shorter keys (no need for signing).

@jsign
Copy link
Contributor

jsign commented Nov 1, 2019

Ah, I was thinking that the ?key= part was created the first time a follower was invited in the thread. So, the way yo mention avoids what I described.

This means that it exists a shared key for all log writers.

Maybe stupid question: if non-follower roles should have read-access to all the thread logs, and now non-follower roles have a shared key: why this key isn't the actual read key of all logs? (and lower key management complexity?)

@sanderpick
Copy link
Member Author

Right, I was thinking above that the key would be created dynamically, but then you got me thinking.

As for the single read key, that's a good question. Couple thoughts:

  • It's still an open question whether or not a log should be able to be used in multiple threads
  • Have log-based read keys might make key rotation easier (for blocking a peer)

@jsign
Copy link
Contributor

jsign commented Nov 1, 2019

* It's still an open question whether or not a log should be able to be used in multiple threads

Maybe the safe bet is to keep them separate (key and read key) to avoid handcuffs and leave it flexible.

* Have log-based read keys might make key rotation easier (for blocking a peer)

Now that you mention that. In that case the key should also be changed? (to avoid blocked peer to decrypt again the rotated key) Or can we assume all followers know that that peer was blocked to ignore requests?

@sanderpick sanderpick modified the milestones: Sprint 22, Sprint 23 Nov 4, 2019
@sanderpick
Copy link
Member Author

As per much Slack chatting, closing this in favor of just using the same read and follow keys for all logs.

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