mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
crypto: add length prefix to handshake.
As per BOLT#1. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6a062d8527
commit
923313e3d3
@ -40,6 +40,7 @@ struct key_negotiate {
|
||||
u8 seckey[32];
|
||||
|
||||
/* Our pubkey, their pubkey. */
|
||||
le32 keylen;
|
||||
u8 our_sessionpubkey[33], their_sessionpubkey[33];
|
||||
|
||||
/* Callback once it's all done. */
|
||||
@ -464,13 +465,60 @@ static struct io_plan *keys_exchanged(struct io_conn *conn, struct peer *peer)
|
||||
return peer_write_packet(conn, peer, auth, receive_proof);
|
||||
}
|
||||
|
||||
/* Read and ignore any extra bytes... */
|
||||
static struct io_plan *discard_extra(struct io_conn *conn, struct peer *peer)
|
||||
{
|
||||
struct key_negotiate *neg = peer->io_data->neg;
|
||||
size_t len = le32_to_cpu(neg->keylen);
|
||||
|
||||
/* BOLT#1: Additional fields MAY be added, and MUST be
|
||||
* included in the `length` field. These MUST be ignored by
|
||||
* implementations which do not understand them. */
|
||||
if (len > sizeof(neg->their_sessionpubkey)) {
|
||||
char *discard;
|
||||
|
||||
len -= sizeof(neg->their_sessionpubkey);
|
||||
discard = tal_arr(neg, char, len);
|
||||
return io_read(conn, discard, len, keys_exchanged, peer);
|
||||
}
|
||||
|
||||
return keys_exchanged(conn, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *session_key_receive(struct io_conn *conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
struct key_negotiate *neg = peer->io_data->neg;
|
||||
|
||||
/* BOLT#1: The `length` field is the length after the field
|
||||
itself, and MUST be 33 or greater. */
|
||||
if (le32_to_cpu(neg->keylen) < sizeof(neg->their_sessionpubkey)) {
|
||||
log_unusual(peer->log, "short session key length %u",
|
||||
le32_to_cpu(neg->keylen));
|
||||
return io_close(conn);
|
||||
}
|
||||
|
||||
/* BOLT#1: `length` MUST NOT exceed 1MB (1048576 bytes). */
|
||||
if (le32_to_cpu(neg->keylen) > 1048576) {
|
||||
log_unusual(peer->log, "Oversize session key length %u",
|
||||
le32_to_cpu(neg->keylen));
|
||||
return io_close(conn);
|
||||
}
|
||||
|
||||
log_debug(peer->log, "Session key length %u", le32_to_cpu(neg->keylen));
|
||||
|
||||
/* Now read their key. */
|
||||
return io_read(conn, neg->their_sessionpubkey,
|
||||
sizeof(neg->their_sessionpubkey), keys_exchanged, peer);
|
||||
sizeof(neg->their_sessionpubkey), discard_extra, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *session_key_len_receive(struct io_conn *conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
struct key_negotiate *neg = peer->io_data->neg;
|
||||
/* Read the amount of data they will send.. */
|
||||
return io_read(conn, &neg->keylen, sizeof(neg->keylen),
|
||||
session_key_receive, peer);
|
||||
}
|
||||
|
||||
static void gen_sessionkey(secp256k1_context *ctx,
|
||||
@ -483,6 +531,15 @@ static void gen_sessionkey(secp256k1_context *ctx,
|
||||
} while (!secp256k1_ec_pubkey_create(ctx, pubkey, seckey));
|
||||
}
|
||||
|
||||
static struct io_plan *write_sessionkey(struct io_conn *conn, struct peer *peer)
|
||||
{
|
||||
struct key_negotiate *neg = peer->io_data->neg;
|
||||
|
||||
return io_write(conn, neg->our_sessionpubkey,
|
||||
sizeof(neg->our_sessionpubkey),
|
||||
session_key_len_receive, peer);
|
||||
}
|
||||
|
||||
struct io_plan *peer_crypto_setup(struct io_conn *conn, struct peer *peer,
|
||||
struct io_plan *(*cb)(struct io_conn *,
|
||||
struct peer *))
|
||||
@ -504,6 +561,7 @@ struct io_plan *peer_crypto_setup(struct io_conn *conn, struct peer *peer,
|
||||
&sessionkey,
|
||||
SECP256K1_EC_COMPRESSED);
|
||||
assert(outputlen == sizeof(neg->our_sessionpubkey));
|
||||
return io_write(conn, neg->our_sessionpubkey, outputlen,
|
||||
session_key_receive, peer);
|
||||
neg->keylen = cpu_to_le32(sizeof(neg->our_sessionpubkey));
|
||||
return io_write(conn, &neg->keylen, sizeof(neg->keylen),
|
||||
write_sessionkey, peer);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user