Re: [capnproto] Implementing SecretHandshake secure-connection support in C++

2022-01-12 Thread 'Kenton Varda' via Cap'n Proto
Sorry for the long delay in replying, I had a baby the day you sent this!

This is neat! How many round trips are needed to set up a connection?

When Cap'n Proto gets three-party handoff support, I'm hoping we can do
0-RTT encrypted session setup after introductions. Not many protocols seem
to consider this use case though.

On Tue, Dec 14, 2021 at 2:05 PM Jens Alfke  wrote:

> The handshake also produces two session keys, which are then used to
> encrypt the channel with the 256-bit symmetric XSalsa20 cipher. (This is
> not strictly speaking part of the SecretHandshake protocol, which ends
> after key agreement. Scuttlebutt uses a different encryption scheme based
> on libSodium’s “secret box”.)
>
Hmm if you're using a plain xsalsa20 stream and not secret boxes, does that
mean you're implementing only encryption, not authentication? Note that
XSalsa20 and related ciphers work by generating a random stream, and then
XORing it with the plaintext. So although the attacker can't decrypt the
bytes, they can flip individual bits in the ciphertext and this will result
in the same bit being flipped in the plaintext. Secret boxes add a MAC to
each block which allows the receiver to verify that the bits haven't been
tampered with.

-Kenton

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQn8W%3DyZPQ%3DD%2BjwUAPvQJQj0XR-EKb1yFEtkwpt9jzYCow%40mail.gmail.com.


Re: [capnproto] How can a server method get info about the client connection?

2022-01-12 Thread 'Kenton Varda' via Cap'n Proto
Hi Jens,

Sorry again for the delay in replying.

The trick here is that you want to construct your "bootstrap" capability
with knowledge of the client, and pass that knowledge on to any
capabilities that you pass to that client. So you'd end up with a different
server object for each connected client. This approach plays nicely with
Cap'n Proto's capability-based security model, whereas attaching
authentication information to individual RPC calls would go against
capability-based security. This becomes especially important in scenarios
where lots of different objects are being passed around between a bunch of
nodes.

The C++ RPC implementation has something called "BootstrapFactory" which
helps you arrange to create a new bootstrap for each client.

-Kenton

On Thu, Dec 16, 2021 at 11:41 AM Jens Alfke  wrote:

> Now that I've implemented authenticated connections, *I need my
> server-side methods to be able to find out the identity (public key) of the
> connected peer*. So for example, my method
> LibraryImpl::checkoutBook(isbn) needs to check the identity of the client
> (as given in the SecretHandshake when connecting) to determine if they have
> permission to get that book.
>
> (A different example that doesn't involve SecretHandshake is one where a
> server-side method wants to look at the IP address of the client. Or, if
> using TLS, the client's TLS cert.)
>
> What's the best way to do this? I'm using my modified version of
> EzRpcServer, and I'm getting familiar with its innards but I can't claim to
> really understand this stuff yet. It appears that the "mainInterface"
> capability vended by the server is a singleton, shared by all clients, so I
> can't stuff per-client info into it. The point of vending is the restore()
> method, but that method can't tell what client it's being called on behalf
> of...
>
> --Jens
>
> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to capnproto+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/b89502d7-8450-4f97-8c3a-ffdb9a4b4663n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQnDMph%2BbzM-3yF1031axNGnFd-J21NRD_cEpeexMjV8gQ%40mail.gmail.com.


Re: [capnproto] Implementing SecretHandshake secure-connection support in C++

2022-01-12 Thread Jens Alfke



> On Jan 12, 2022, at 9:22 AM, Kenton Varda  wrote:
> 
> Sorry for the long delay in replying, I had a baby the day you sent this!

Congratulations! 🎉 I remember those days...

> This is neat! How many round trips are needed to set up a connection?

There are four messages: C->S, S->C, C->S, S->C. In the current implementation 
they happen one at a time, so I guess that’s two round trips? But it looks as 
though messages 1 & 2 can be sent concurrently, and also 3 & 4.

I dimly recall that there are some additional TCP hacks one can do, to 
piggyback a small payload on the initial packets that open the connection, but 
I don’t feel like cracking open TCP/IP Illustrated right now :-p

> Hmm if you're using a plain xsalsa20 stream and not secret boxes, does that 
> mean you're implementing only encryption, not authentication? Note that 
> XSalsa20 and related ciphers work by generating a random stream, and then 
> XORing it with the plaintext. So although the attacker can't decrypt the 
> bytes, they can flip individual bits in the ciphertext and this will result 
> in the same bit being flipped in the plaintext.

Yeah, there are no integrity checks in the data stream, and I agree that’s a 
weakness*. Adding MACs requires adding a block- or message-oriented layer on 
top, like SecretBox, the way that Scuttlebutt does. This feels like redundant 
effort since Cap’nP also is itself message-oriented; my guess is that there’s a 
higher level API inside Cap’nP that exposes the message framing, and the MAC 
could be added there, but I have not yet delved deeper into the way Cap’nP 
works. (Hints welcome.)

(Or if there’s a clever stream-based way to insert MACs without having to build 
a framing layer, that would be even better. I’ve read my share of crypto 
textbooks, maybe I’ve just forgotten that bit.)

—Jens

* I should probably call this out in the readme, shouldn’t I.

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/D78A1434-B928-43D4-951D-5CFA2E021B8E%40mooseyard.com.


Re: [capnproto] Implementing SecretHandshake secure-connection support in C++

2022-01-12 Thread 'Kenton Varda' via Cap'n Proto
On Wed, Jan 12, 2022 at 12:01 PM Jens Alfke  wrote:

> Yeah, there are no integrity checks in the data stream, and I agree that’s
> a weakness*. Adding MACs requires adding a block- or message-oriented layer
> on top, like SecretBox, the way that Scuttlebutt does. This feels like
> redundant effort since Cap’nP also is itself message-oriented; my guess is
> that there’s a higher level API inside Cap’nP that exposes the message
> framing, and the MAC could be added there, but I have not yet delved deeper
> into the way Cap’nP works. (Hints welcome.)
>

You might want to look at the `capnp::MessageStream` abstraction, instead
of `kj::AsyncIoStream`. It lets you see whole messages, which makes it
easier to customize the framing.

-Kenton

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQ%3DN_iafGGMxh5kktODf0Bs_gALgO5hFpdmh%3DR94-Ay_3g%40mail.gmail.com.


[capnproto] Noob question: Can an interface method return null?

2022-01-12 Thread Jens Alfke
This seems like a dumb question, but I’ve been unable to find an answer. Does 
the RPC system support null values? In particular, if an RPC method returns an 
interface, is it able to return null?

Say Widget is an interface, and in another interface I’ve got a method
widgetNamed @1 (name: String) -> (widget: Widget);
Can this method return null? I’m beginning to suspect it can’t, because when it 
tries to I get an error "Pipeline call on a request that returned no 
capabilities or was already closed”. (The implementation is in C++; to return 
null it just abstains from calling context.getResults().setWidget().)

If it can’t, what is the idiomatic way to provide an optional return value? Do 
I return an exception, or do I create my own `Optional` type as a union?

—Jens

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/5862EBA9-F772-44A4-9736-72F70AAB0B86%40mooseyard.com.


Re: [capnproto] Noob question: Can an interface method return null?

2022-01-12 Thread 'Kenton Varda' via Cap'n Proto
Any pointer type, including interfaces, can be null.

I think the problem here, though, is that you're making a pipelined call on
the widget before the `wigitNamed()` RPC call has actually completed, and
then later on `widgetNamed()` is completing with a null result, and so the
pipelined call fails. The error you are seeing is a little
confusingly-worded but is in fact the error that would be expected in this
scenario.

So yeah, you *are* returning null correctly, it's just that on the client
side you're trying to make a call to the null capability before the client
actually finds out that it is null.

-Kenton

On Wed, Jan 12, 2022 at 5:05 PM Jens Alfke  wrote:

> This seems like a dumb question, but I’ve been unable to find an answer. *Does
> the RPC system support null values?* In particular, if an RPC method
> returns an interface, is it able to return null?
>
> Say Widget is an interface, and in another interface I’ve got a method
> widgetNamed @1 (name: String) -> (widget: Widget);
> Can this method return null? I’m beginning to suspect it can’t, because
> when it tries to I get an error "Pipeline call on a request that returned
> no capabilities or was already closed”. (The implementation is in C++; to
> return null it just abstains from calling context.getResults().setWidget().)
>
> If it can’t, what is the idiomatic way to provide an optional return
> value? Do I return an exception, or do I create my own `Optional` type as a
> union?
>
> —Jens
>
> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to capnproto+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/5862EBA9-F772-44A4-9736-72F70AAB0B86%40mooseyard.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQnWLTYVBRgA4saKXSKOEADwo4riEnOqN8DEMSLKoheVLw%40mail.gmail.com.


Re: [capnproto] Implementing SecretHandshake secure-connection support in C++

2022-01-12 Thread Jens Alfke

>> Hmm if you're using a plain xsalsa20 stream and not secret boxes, does that 
>> mean you're implementing only encryption, not authentication? Note that 
>> XSalsa20 and related ciphers work by generating a random stream, and then 
>> XORing it with the plaintext.

FYI: It turns out that my stream-encryption code is totally broken anyway. I 
naively believed that Sodium’s `crypto_stream_xor` implemented a stream cipher, 
as the name implies — but it doesn’t. The key and nonce parameters are both 
const, so it’s stateless, and just xor’s the buffer with the same bit-stream 
every time it’s called.

I am not a cryptographer, but I find this baffling and pointless. Why call this 
a “stream cipher” when the API only allows you to encrypt a single 
(variable-size) block of data?

Looks like I’m forced to implement a chunk-based protocol after all. Good news 
is it’ll be tamper-proof.

—Jens

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/FD4A7BDA-5DF1-4F4B-B574-57EFB4DE72FB%40mooseyard.com.