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

per-session cryptography key pair in CapTP layer? #53

Open
dckc opened this issue May 23, 2023 · 11 comments
Open

per-session cryptography key pair in CapTP layer? #53

dckc opened this issue May 23, 2023 · 11 comments
Assignees

Comments

@dckc
Copy link
Collaborator

dckc commented May 23, 2023

As noted in #42 (comment) , the Agoric CapTP API doesn't use a session key pair.

@tsyesika writes:

There certainly could be more moved into netlayers that I've currently put in CapTP, however the interface between the two specifications would have to be higher, which isn't necessarily a bad thing, but just something to keep in mind. The netlayer currently is only responsible for opening up channel between two sessions and delivering messages through this channel, it's fairly limited in scope.

@zenhack writes:

I think having connection semantics cleanly separated from the netlayer is important. Note, in particular, capnp often gets used over local unix sockets, where layering crypto on top would be silly...

@zenhack
Copy link
Collaborator

zenhack commented May 24, 2023

I will also add that in addition to it just feeling silly, it forces a hard-dependency on some crypto libraries where they aren't really needed. E.g. if you wanted to have a netlayer that let a js client running in a browser talk to the server over a (TLS) websocket, pulling in an ed25519 signature implementation would bloat bundle size for no reason but spec compliance.

@tsyesika
Copy link
Contributor

tsyesika commented Jun 1, 2023

I just want to add some more information here. The crypto stuff is fairly limited in scope and is really only required for third party handoffs. I think we could push this down into the netlayer and there might be better ways to do it based on the context the netlayer is operating under. For example for unix sockets on the same machine, perhaps this could be done with passing around anonymous file handlers through the connection.

I think it'd be good if we could explore this. We do need to ensure there is a secure way to perform third party handoffs though and I suspect most netlayers may need something like the certificate handoff solution that exists today.

@zenhack
Copy link
Collaborator

zenhack commented Jun 1, 2023

I'd encourage folks looking over https://github.com/capnproto/capnproto/blob/455824528cd01268d4f9491a0df961c9a3678852/c%2B%2B/src/capnp/rpc.capnp#L1411-L1512, which sketches a possible way to abstract out the netlayer (which the comments call a "vat network").

@zenhack
Copy link
Collaborator

zenhack commented Jun 13, 2023

Per discussion, at the meeting, I'm going to assign some folks to request that they read over the above, as a starting point for how this might be abstracted out.

@zenhack
Copy link
Collaborator

zenhack commented Jun 13, 2023

(Note: if folks from various stakeholder projects want to reassign who from their team is going to look at this, please do; I picked some folks relatively arbitrarily).

@dckc dckc assigned kriskowal and unassigned dckc Jun 13, 2023
@kriskowal
Copy link
Collaborator

I’m on the hook to review this. I’m also barely qualified to review this.

I can say immediately, despite lack of qualification, that I favor a layering like:

  1. pluggable transport (e.g., TCP)
  2. pluggable encryption for at least privacy (e.g., TLS with self-signed x509, or just relying on the privacy of a UNIX domain socket or Windows named pipe)
  3. pluggable message framing (e.g., netstring, web message ports)
  4. just one concrete data representation (e.g., syrup)
  5. the bulk of o’cap’n: session scoped messages, no 3ph, and no opinions about the bootstrap object
  6. the rest of o’cap’n: three-party-handoff, provided cryptographic material, a delegate implementation, and a conventional bootstrap wrapper object for 3ph
  7. : the application’s bootstrap and subsequently reachable protocols

I don’t know the layer that works best for authentication. I doubt we get it from TLS and self-signed certs. It seems like a concern that touches upon the bottom-most and top-most layers of O’Cap’n although completely orthogonal to the middle, and I’m eager to understand more about Goblins’s design choices.

@zenhack
Copy link
Collaborator

zenhack commented Jun 26, 2023

I broadly agree with your outline. (5) in particular gets at what I feel so strongly about here: the basic point-to-point rpc stuff should be as independent as possible from the layers above & below it. This means in particular that any messages relating to connection setup should be pushed down into (2), and may simply not be required for some netlayers.

The way capnp is specified, you have an interesting situation where (2) and (6) likely care about each other, but the layers in between do not.


tangent: it would be nice if we had different terminology for what capnp calls bootstrap vs. what E called NonceLocator -- goblins seems to be using bootstrap to refer to the latter, but as you described there's an "application" bootstrap object, which is what capnp uses the term for.

@kriskowal
Copy link
Collaborator

kriskowal commented Jun 26, 2023

Thanks @zenhack, evoking “nonce locator” was useful. Agoric’s CapTP also names “bootstrap” the first object presented to the connection on either side (if requested by the other side!), which is clearly how we would necessarily present the nonce locator to the wire. So, I can see how we would arrive at a conflation of terms. I propose a strawpoke:

  • “bootstrap” the first object presented to the interlocutor
  • “nonce locator” the object for obtaining or reobtaining a reference to any object previously transmitted over any open session
  • “public API facet” the API presented to any authenticated interlocutor, which is necessarily reachable starting at “bootstrap” if not the bootstrap proper.

At Agoric, currently the bootstrap object is always the public facet, if there is one. I figure we have a few layering options. Currently in Agoric CapTP, getBootstrap is a special initialization message.

  • There could be an alternate initialization message for getting a nonce locator, if that is supported. A peer could concurrently request both the public facet and nonce locator.
  • The bootstrap object could conventionally provide separate methods for getting the public facet and nonce locator.
  • The nonce locator could have a method for getting the public facet.

@zenhack
Copy link
Collaborator

zenhack commented Jun 26, 2023

At Agoric, currently the bootstrap object is always the public facet, if there is one.

The same is true of capnp.

Some things to note:

  • There is no reified nonce locator in capnp; instead, there are primitive message types for Accept and Provide, which are to be handled directly, rather than dispatched via the usual call logic. I don't think the implications of this run terribly deep, but it at least means not having to juggle these two distinct possible uses of a "bootstrap" object (in your terminology).
  • The Bootstrap message type originally corresponded to NonceLocator's restore method. The history of it is worth a read: https://github.com/capnproto/capnproto/blob/495cebe8673a0820e3202de66970059be70d4928/c%2B%2B/src/capnp/rpc.capnp#L323-L386

@tsyesika
Copy link
Contributor

Hey,

Sorry it took me so long to get to this, I've had a lot going on this month.

I've looked at the RPC document you linked and if I'm understanding it correctly it seems like it's putting creating connections and "handing off" connections into the netlayer. This is obviously connections, not objects, such as in the case of 3PH, however I think there can be a few things here to note.

We could do something similar and have all the 3PH lifted from the CapTP spec and put instead into the netlayer spec and have this part of their domain. If I try and think of how we could do this, I could imagine that each netlayer has the following:

  • an out-of-band mechanism to connect to a new OCapN machine/node: This would basically be how it works today with sharing an OCapN locator which encodes the ways to connect to a given node so the other session is able to establish a new connection. This could be used when the two sessions you're performing a handoff between are on different netlayer types.
  • an out-of-band mechanism to perform a 3PH: This would be similar to how 3PH is specified in the draft spec. It's a certificate based approach which uses crypto to create and verify a certificate to allow 3PH where the two sessions (receiver and exporter) are using different netlayer types. Something which we could add is negotiating the crypto supported by each session, instead of specifying a specific set of crypto algorithms - we probably want this anyway I'm guessing.

In addition to this, if the netlayer would like it could provide:

  • an in-band mechanism to connect to a new OCapN machine/node: This would be something specific to the netlayer which can be used by the receiver to connect to the exporter. I'm not sure, but you'd have to have a way to ensure you only have one connection to any given OCapN node, this might raise eq? issues, something to investigate.
  • an in-band mechanism to perform a 3PH: Again similar to the above maybe the netlayer provides a mechanism to securely do handoffs without crypto, maybe for example with unix sockets it could be an anonymous file handle which represents some capability - not sure.

This would allow in-band 3PH to use a better mechanism one exists and can be used, but when performing a handoff to a node using a different netlayer it has the universal certificate mechanism that is netlayer agnostic. There could be situations where a node only supports one netlayer type and thus doesn't want to support the out-of-band mechanisms and that'd be okay too.

WYDT?

@kriskowal
Copy link
Collaborator

I cannot proceed without first acknowledging that we shall sorely miss @zenhack and I for one wish to honor his participation by continuing to make progress in this endeavor mindful of their vision.

@tsyesika I like this outline except that @warner and I concur that we actually do want to select a particular set of cryptographic algorithms such that any hand-off denotes a single (signer key, signer assigned identifier) pair such that a difference in transport cannot confuse the identity of a hand-off object. The layering we’re imaging looks like:

  • CapTP consists of layers:
    • VatTP / net layer (also consists of layers:)
      • Transport and Message Framing (pluggable, e.g., WebSocket, MessagePort) which may in turn consist of layers:
        • Transport (pluggable, e.g., Tor)
        • Message Framing (pluggable, e.g., netstring, structured clone)
      • Signing (not pluggable, such that (key, id) is consistent over all VatTPs)
      • Encoding (e.g., JSON, Syrup, possibly pluggable)
    • Messaging (the bulk of CapTP)

And a connection hint consists of a full reckoning of the combination of VatTP layers and an address specific to that combination.

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

6 participants