crypto: add length prefix to handshake.

As per BOLT#1.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-03-15 17:10:42 +10:30
parent 6a062d8527
commit 923313e3d3

View File

@ -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);
}