connectd: do decryption for peers.

We temporarily hack to sync_crypto_write/sync_crypto_read functions to
not do any crypto, and do it all in connectd.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-01-08 23:52:29 +10:30
parent 71f736678f
commit a2b3d335bb
5 changed files with 95 additions and 93 deletions

View File

@ -12,6 +12,8 @@
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <wire/wire.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>
void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
{
@ -19,10 +21,8 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
bool post_sabotage = false, post_close;
int type = fromwire_peektype(msg);
#endif
u8 *enc;
status_peer_io(LOG_IO_OUT, NULL, msg);
enc = cryptomsg_encrypt_msg(NULL, &pps->cs, msg);
#if DEVELOPER
switch (dev_disconnect(type)) {
@ -44,9 +44,8 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
break;
}
#endif
if (!write_all(pps->peer_fd, enc, tal_count(enc)))
if (!wire_sync_write(pps->peer_fd, msg))
peer_failed_connection_lost();
tal_free(enc);
#if DEVELOPER
if (post_sabotage)
@ -101,31 +100,10 @@ void sync_crypto_write_no_delay(struct per_peer_state *pps,
u8 *sync_crypto_read(const tal_t *ctx, struct per_peer_state *pps)
{
u8 hdr[18], *enc, *dec;
u16 len;
if (!read_all(pps->peer_fd, hdr, sizeof(hdr))) {
status_debug("Failed reading header: %s", strerror(errno));
peer_failed_connection_lost();
}
if (!cryptomsg_decrypt_header(&pps->cs, hdr, &len)) {
status_debug("Failed hdr decrypt with rn=%"PRIu64,
pps->cs.rn-1);
peer_failed_connection_lost();
}
enc = tal_arr(ctx, u8, len + 16);
if (!read_all(pps->peer_fd, enc, tal_count(enc))) {
status_debug("Failed reading body: %s", strerror(errno));
peer_failed_connection_lost();
}
dec = cryptomsg_decrypt_body(ctx, &pps->cs, enc);
tal_free(enc);
u8 *dec = wire_sync_read(ctx, pps->peer_fd);
if (!dec)
peer_failed_connection_lost();
else
status_peer_io(LOG_IO_IN, NULL, dec);
return dec;

View File

@ -452,7 +452,6 @@ static struct peer *new_peer(struct daemon *daemon,
peer->final_msg = NULL;
peer->subd_in = NULL;
peer->peer_in = NULL;
peer->sent_to_subd = NULL;
peer->sent_to_peer = NULL;
peer->peer_outq = msg_queue_new(peer);
peer->subd_outq = msg_queue_new(peer);
@ -1988,7 +1987,6 @@ static void peer_final_msg(struct io_conn *conn,
if (peer) {
/* Log and encrypt message for peer. */
status_peer_io(LOG_IO_OUT, &id, finalmsg);
finalmsg = cryptomsg_encrypt_msg(NULL, &pps->cs, take(finalmsg));
multiplex_final_msg(peer, take(finalmsg));
}
}

View File

@ -3,12 +3,20 @@
#include "config.h"
#include <assert.h>
#include <ccan/io/io.h>
#include <common/cryptomsg.h>
#include <common/per_peer_state.h>
#include <common/status.h>
#include <common/utils.h>
#include <connectd/multiplex.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <wire/wire_io.h>
void queue_peer_msg(struct peer *peer, const u8 *msg TAKES)
{
msg_enqueue(peer->peer_outq, msg);
}
/* These four function handle subd->peer */
static struct io_plan *after_final_msg(struct io_conn *peer_conn,
@ -24,25 +32,39 @@ static struct io_plan *after_final_msg(struct io_conn *peer_conn,
return io_close(peer_conn);
}
static struct io_plan *encrypt_and_send(struct peer *peer,
const u8 *msg TAKES,
struct io_plan *(*next)
(struct io_conn *peer_conn,
struct peer *peer))
{
/* We free this and the encrypted version in next write_to_peer */
peer->sent_to_peer = cryptomsg_encrypt_msg(peer, &peer->pps->cs, msg);
return io_write(peer->to_peer,
peer->sent_to_peer,
tal_bytelen(peer->sent_to_peer),
next, peer);
}
static struct io_plan *write_to_peer(struct io_conn *peer_conn,
struct peer *peer)
{
const u8 *msg;
assert(peer->to_peer == peer_conn);
/* Free last sent one (if any) */
tal_free(peer->sent_to_peer);
peer->sent_to_peer = tal_free(peer->sent_to_peer);
/* Pop tail of send queue */
peer->sent_to_peer = msg_dequeue(peer->peer_outq);
msg = msg_dequeue(peer->peer_outq);
/* Nothing to send? */
if (!peer->sent_to_peer) {
if (!msg) {
/* Send final once subd is not longer connected */
if (peer->final_msg && !peer->to_subd) {
return io_write(peer_conn,
return encrypt_and_send(peer,
peer->final_msg,
tal_bytelen(peer->final_msg),
after_final_msg, peer);
after_final_msg);
}
/* Tell them to read again, */
io_wake(&peer->subd_in);
@ -52,10 +74,7 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
write_to_peer, peer);
}
return io_write(peer_conn,
peer->sent_to_peer,
tal_bytelen(peer->sent_to_peer),
write_to_peer, peer);
return encrypt_and_send(peer, take(msg), write_to_peer);
}
static struct io_plan *read_from_subd(struct io_conn *subd_conn,
@ -63,15 +82,10 @@ static struct io_plan *read_from_subd(struct io_conn *subd_conn,
static struct io_plan *read_from_subd_done(struct io_conn *subd_conn,
struct peer *peer)
{
size_t len = ((size_t *)peer->subd_in)[1023];
assert(peer->to_subd == subd_conn);
/* Trim to length */
tal_resize(&peer->subd_in, len);
/* Tell them to write. */
msg_enqueue(peer->peer_outq, take(peer->subd_in));
/* Tell them to encrypt & write. */
queue_peer_msg(peer, take(peer->subd_in));
peer->subd_in = NULL;
/* Wait for them to wake us */
return io_wait(subd_conn, &peer->subd_in, read_from_subd, peer);
}
@ -79,14 +93,7 @@ static struct io_plan *read_from_subd_done(struct io_conn *subd_conn,
static struct io_plan *read_from_subd(struct io_conn *subd_conn,
struct peer *peer)
{
/* We stash the length at the end */
size_t *buf = tal_arr(peer, size_t, 1024);
assert(peer->to_subd == subd_conn);
peer->subd_in = (u8 *)buf;
return io_read_partial(subd_conn, peer->subd_in,
sizeof(size_t) * 1023,
&buf[1023],
return io_read_wire(subd_conn, peer, &peer->subd_in,
read_from_subd_done, peer);
}
@ -94,17 +101,15 @@ static struct io_plan *read_from_subd(struct io_conn *subd_conn,
static struct io_plan *write_to_subd(struct io_conn *subd_conn,
struct peer *peer)
{
const u8 *msg;
assert(peer->to_subd == subd_conn);
/* Free last sent one (if any) */
tal_free(peer->sent_to_subd);
/* Pop tail of send queue */
peer->sent_to_subd = msg_dequeue(peer->subd_outq);
msg = msg_dequeue(peer->subd_outq);
/* Nothing to send? */
if (!peer->sent_to_subd) {
/* Tell them to read again, */
if (!msg) {
/* Tell them to read again. */
io_wake(&peer->peer_in);
/* Wait for them to wake us */
@ -112,42 +117,59 @@ static struct io_plan *write_to_subd(struct io_conn *subd_conn,
write_to_subd, peer);
}
return io_write(subd_conn,
peer->sent_to_subd,
tal_bytelen(peer->sent_to_subd),
write_to_subd, peer);
return io_write_wire(subd_conn, take(msg), write_to_subd, peer);
}
static struct io_plan *read_from_peer(struct io_conn *peer_conn,
static struct io_plan *read_hdr_from_peer(struct io_conn *peer_conn,
struct peer *peer);
static struct io_plan *read_from_peer_done(struct io_conn *peer_conn,
static struct io_plan *read_body_from_peer_done(struct io_conn *peer_conn,
struct peer *peer)
{
size_t len = ((size_t *)peer->peer_in)[1023];
assert(peer->to_peer == peer_conn);
u8 *decrypted;
/* Trim to length */
tal_resize(&peer->peer_in, len);
decrypted = cryptomsg_decrypt_body(NULL, &peer->pps->cs,
peer->peer_in);
if (!decrypted)
return io_close(peer_conn);
tal_free(peer->peer_in);
/* Tell them to write. */
msg_enqueue(peer->subd_outq, take(peer->peer_in));
peer->peer_in = NULL;
msg_enqueue(peer->subd_outq, take(decrypted));
/* Wait for them to wake us */
return io_wait(peer_conn, &peer->peer_in, read_from_peer, peer);
return io_wait(peer_conn, &peer->peer_in, read_hdr_from_peer, peer);
}
static struct io_plan *read_from_peer(struct io_conn *peer_conn,
static struct io_plan *read_body_from_peer(struct io_conn *peer_conn,
struct peer *peer)
{
u16 len;
if (!cryptomsg_decrypt_header(&peer->pps->cs, peer->peer_in, &len))
return io_close(peer_conn);
tal_resize(&peer->peer_in, (u32)len + CRYPTOMSG_BODY_OVERHEAD);
return io_read(peer_conn, peer->peer_in, tal_count(peer->peer_in),
read_body_from_peer_done, peer);
}
static struct io_plan *read_hdr_from_peer(struct io_conn *peer_conn,
struct peer *peer)
{
/* We stash the length at the end */
size_t *buf = tal_arr(peer, size_t, 1024);
assert(peer->to_peer == peer_conn);
peer->peer_in = (u8 *)buf;
return io_read_partial(peer_conn, peer->peer_in,
sizeof(size_t) * 1023,
&buf[1023],
read_from_peer_done, peer);
/* BOLT #8:
*
* ### Receiving and Decrypting Messages
*
* In order to decrypt the _next_ message in the network
* stream, the following steps are completed:
*
* 1. Read _exactly_ 18 bytes from the network buffer.
*/
peer->peer_in = tal_arr(peer, u8, CRYPTOMSG_HDR_SIZE);
return io_read(peer_conn, peer->peer_in, CRYPTOMSG_HDR_SIZE,
read_body_from_peer, peer);
}
static struct io_plan *subd_conn_init(struct io_conn *subd_conn, struct peer *peer)
@ -200,7 +222,7 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
tal_add_destructor2(peer_conn, destroy_peer_conn, peer);
return io_duplex(peer_conn,
read_from_peer(peer_conn, peer),
read_hdr_from_peer(peer_conn, peer),
write_to_peer(peer_conn, peer));
}

View File

@ -24,8 +24,8 @@ struct peer {
/* Output buffers. */
struct msg_queue *subd_outq, *peer_outq;
/* Sent buffers (for freeing after sending) */
const u8 *sent_to_subd, *sent_to_peer;
/* Peer sent buffer (for freeing after sending) */
const u8 *sent_to_peer;
};
/* Set up peer->to_subd; sets fd_for_subd to pass to lightningd. */
@ -38,4 +38,8 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
/* Send this message to peer and disconnect. */
void multiplex_final_msg(struct peer *peer,
const u8 *final_msg TAKES);
/* Inject a message into the output stream */
void queue_peer_msg(struct peer *peer, const u8 *msg TAKES);
#endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */

View File

@ -27,7 +27,7 @@ struct io_plan *io_read_wire_(struct io_conn *conn,
/* Write message from data (tal_count(data) gives length). data can be take() */
struct io_plan *io_write_wire_(struct io_conn *conn,
const u8 *data,
const u8 *data TAKES,
struct io_plan *(*next)(struct io_conn *, void *),
void *next_arg);