From 2d09af8d56b3781ed539d67025cb2950ef8fc5e8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 31 Jan 2024 14:53:33 +1030 Subject: [PATCH] gossipd: take signature checks out of routing.c Signed-off-by: Rusty Russell --- gossipd/Makefile | 1 + gossipd/routing.c | 165 +++------------- gossipd/sigcheck.c | 184 ++++++++++++++++++ gossipd/sigcheck.h | 29 +++ gossipd/test/run-check_channel_announcement.c | 112 ++--------- 5 files changed, 262 insertions(+), 229 deletions(-) create mode 100644 gossipd/sigcheck.c create mode 100644 gossipd/sigcheck.h diff --git a/gossipd/Makefile b/gossipd/Makefile index 061d08167..5a12f93c1 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -8,6 +8,7 @@ GOSSIPD_HEADERS_WSRC := gossipd/gossipd_wiregen.h \ gossipd/queries.h \ gossipd/routing.h \ gossipd/txout_failures.h \ + gossipd/sigcheck.h \ gossipd/seeker.h GOSSIPD_HEADERS := $(GOSSIPD_HEADERS_WSRC) gossipd/broadcast.h diff --git a/gossipd/routing.c b/gossipd/routing.c index 23c093d6d..45721133a 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifndef SUPERVERBOSE @@ -579,96 +580,6 @@ struct chan *new_chan(struct routing_state *rstate, return chan; } -/* Verify the signature of a channel_update message */ -static u8 *check_channel_update(const tal_t *ctx, - const struct node_id *node_id, - const secp256k1_ecdsa_signature *node_sig, - const u8 *update) -{ - /* 2 byte msg type + 64 byte signatures */ - int offset = 66; - struct sha256_double hash; - sha256_double(&hash, update + offset, tal_count(update) - offset); - - if (!check_signed_hash_nodeid(&hash, node_sig, node_id)) - return towire_warningfmt(ctx, NULL, - "Bad signature for %s hash %s" - " on channel_update %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - node_sig), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, update)); - return NULL; -} - -static u8 *check_channel_announcement(const tal_t *ctx, - const struct node_id *node1_id, const struct node_id *node2_id, - const struct pubkey *bitcoin1_key, const struct pubkey *bitcoin2_key, - const secp256k1_ecdsa_signature *node1_sig, - const secp256k1_ecdsa_signature *node2_sig, - const secp256k1_ecdsa_signature *bitcoin1_sig, - const secp256k1_ecdsa_signature *bitcoin2_sig, const u8 *announcement) -{ - /* 2 byte msg type + 256 byte signatures */ - int offset = 258; - struct sha256_double hash; - sha256_double(&hash, announcement + offset, - tal_count(announcement) - offset); - - if (!check_signed_hash_nodeid(&hash, node1_sig, node1_id)) { - return towire_warningfmt(ctx, NULL, - "Bad node_signature_1 %s hash %s" - " on channel_announcement %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - node1_sig), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, announcement)); - } - if (!check_signed_hash_nodeid(&hash, node2_sig, node2_id)) { - return towire_warningfmt(ctx, NULL, - "Bad node_signature_2 %s hash %s" - " on channel_announcement %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - node2_sig), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, announcement)); - } - if (!check_signed_hash(&hash, bitcoin1_sig, bitcoin1_key)) { - return towire_warningfmt(ctx, NULL, - "Bad bitcoin_signature_1 %s hash %s" - " on channel_announcement %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - bitcoin1_sig), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, announcement)); - } - if (!check_signed_hash(&hash, bitcoin2_sig, bitcoin2_key)) { - return towire_warningfmt(ctx, NULL, - "Bad bitcoin_signature_2 %s hash %s" - " on channel_announcement %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - bitcoin2_sig), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, announcement)); - } - return NULL; -} - /* We allow node announcements for this node if it doesn't otherwise exist, so * we can process them once it does exist (a channel_announce is being * validated right now). @@ -889,6 +800,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate, secp256k1_ecdsa_signature node_signature_1, node_signature_2; secp256k1_ecdsa_signature bitcoin_signature_1, bitcoin_signature_2; struct chan *chan; + const char *err; pending = tal(rstate, struct pending_cannouncement); pending->source_peer = tal_dup_or_null(pending, struct node_id, source_peer); @@ -990,17 +902,17 @@ u8 *handle_channel_announcement(struct routing_state *rstate, } /* Note that if node_id_1 or node_id_2 are malformed, it's caught here */ - warn = check_channel_announcement(rstate, - &pending->node_id_1, - &pending->node_id_2, - &pending->bitcoin_key_1, - &pending->bitcoin_key_2, - &node_signature_1, - &node_signature_2, - &bitcoin_signature_1, - &bitcoin_signature_2, - pending->announce); - if (warn) { + err = sigcheck_channel_announcement(tmpctx, + &pending->node_id_1, + &pending->node_id_2, + &pending->bitcoin_key_1, + &pending->bitcoin_key_2, + &node_signature_1, + &node_signature_2, + &bitcoin_signature_1, + &bitcoin_signature_2, + pending->announce); + if (err) { /* BOLT #7: * * - if `bitcoin_signature_1`, `bitcoin_signature_2`, @@ -1010,6 +922,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate, * - MAY close the connection. * - MUST ignore the message. */ + warn = towire_warningfmt(rstate, NULL, "%s", err); goto malformed; } @@ -1585,7 +1498,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, struct bitcoin_blkid chain_hash; u8 direction; struct pending_cannouncement *pending; - u8 *warn; + const char *err; serialized = tal_dup_talarr(tmpctx, u8, update); if (!fromwire_channel_update(serialized, &signature, @@ -1647,7 +1560,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, /* This may be a local channel we don't know about. If it's from a peer, * check signature assuming it's from that peer, and if it's valid, hand to ld */ if (source_peer - && check_channel_update(tmpctx, source_peer, &signature, serialized) == NULL) { + && sigcheck_channel_update(tmpctx, source_peer, &signature, serialized) == NULL) { tell_lightningd_peer_update(rstate, source_peer, short_channel_id, fee_base_msat, fee_proportional_millionths, @@ -1668,8 +1581,8 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, return NULL; } - warn = check_channel_update(rstate, owner, &signature, serialized); - if (warn) { + err = sigcheck_channel_update(tmpctx, owner, &signature, serialized); + if (err) { /* BOLT #7: * * - if `signature` is not a valid signature, using `node_id` @@ -1679,7 +1592,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, * - SHOULD send a `warning` and close the connection. * - MUST NOT process the message further. */ - return warn; + return towire_warningfmt(rstate, NULL, "%s", err); } routing_add_channel_update(rstate, take(serialized), 0, source_peer, force, @@ -1956,7 +1869,6 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann, bool *was_unknown) { u8 *serialized; - struct sha256_double hash; secp256k1_ecdsa_signature signature; u32 timestamp; struct node_id node_id; @@ -1966,6 +1878,7 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann, struct wireaddr *wireaddrs; size_t len = tal_count(node_ann); struct tlv_node_ann_tlvs *na_tlv; + const char *err; if (was_unknown) *was_unknown = false; @@ -1991,31 +1904,10 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann, return NULL; } - sha256_double(&hash, serialized + 66, tal_count(serialized) - 66); - /* If node_id is invalid, it fails here */ - if (!check_signed_hash_nodeid(&hash, &signature, &node_id)) { - /* BOLT #7: - * - * - if `signature` is not a valid signature, using - * `node_id` of the double-SHA256 of the entire - * message following the `signature` field - * (including unknown fields following - * `fee_proportional_millionths`): - * - SHOULD send a `warning` and close the connection. - * - MUST NOT process the message further. - */ - u8 *warn = towire_warningfmt(rstate, NULL, - "Bad signature for %s hash %s" - " on node_announcement %s", - type_to_string(tmpctx, - secp256k1_ecdsa_signature, - &signature), - type_to_string(tmpctx, - struct sha256_double, - &hash), - tal_hex(tmpctx, node_ann)); - return warn; - } + err = sigcheck_node_announcement(tmpctx, &node_id, &signature, + serialized); + if (err) + return towire_warningfmt(rstate, NULL, "%s", err); wireaddrs = fromwire_wireaddr_array(tmpctx, addresses); if (!wireaddrs) { @@ -2026,11 +1918,10 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann, * - SHOULD send a `warning`. * - MAY close the connection. */ - u8 *warn = towire_warningfmt(rstate, NULL, - "Malformed wireaddrs %s in %s.", - tal_hex(tmpctx, wireaddrs), - tal_hex(tmpctx, node_ann)); - return warn; + return towire_warningfmt(rstate, NULL, + "Malformed wireaddrs %s in %s.", + tal_hex(tmpctx, wireaddrs), + tal_hex(tmpctx, node_ann)); } /* May still fail, if we don't know the node. */ diff --git a/gossipd/sigcheck.c b/gossipd/sigcheck.c new file mode 100644 index 000000000..1ca94fdec --- /dev/null +++ b/gossipd/sigcheck.c @@ -0,0 +1,184 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include + +/* Verify the signature of a channel_update message */ +const char *sigcheck_channel_update(const tal_t *ctx, + const struct node_id *node_id, + const secp256k1_ecdsa_signature *node_sig, + const u8 *update) +{ + /* BOLT #7: + * 1. type: 258 (`channel_update`) + * 2. data: + * * [`signature`:`signature`] + * * [`chain_hash`:`chain_hash`] + * * [`short_channel_id`:`short_channel_id`] + * * [`u32`:`timestamp`] + * * [`byte`:`message_flags`] + * * [`byte`:`channel_flags`] + * * [`u16`:`cltv_expiry_delta`] + * * [`u64`:`htlc_minimum_msat`] + * * [`u32`:`fee_base_msat`] + * * [`u32`:`fee_proportional_millionths`] + * * [`u64`:`htlc_maximum_msat`] + */ + /* 2 byte msg type + 64 byte signatures */ + int offset = 66; + struct sha256_double hash; + + sha256_double(&hash, update + offset, tal_count(update) - offset); + + if (!check_signed_hash_nodeid(&hash, node_sig, node_id)) + return tal_fmt(ctx, + "Bad signature for %s hash %s" + " on channel_update %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + node_sig), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, update)); + return NULL; +} + +const char *sigcheck_channel_announcement(const tal_t *ctx, + const struct node_id *node1_id, + const struct node_id *node2_id, + const struct pubkey *bitcoin1_key, + const struct pubkey *bitcoin2_key, + const secp256k1_ecdsa_signature *node1_sig, + const secp256k1_ecdsa_signature *node2_sig, + const secp256k1_ecdsa_signature *bitcoin1_sig, + const secp256k1_ecdsa_signature *bitcoin2_sig, + const u8 *announcement) +{ + /* BOLT #7: + * 1. type: 256 (`channel_announcement`) + * 2. data: + * * [`signature`:`node_signature_1`] + * * [`signature`:`node_signature_2`] + * * [`signature`:`bitcoin_signature_1`] + * * [`signature`:`bitcoin_signature_2`] + * * [`u16`:`len`] + * * [`len*byte`:`features`] + * * [`chain_hash`:`chain_hash`] + * * [`short_channel_id`:`short_channel_id`] + * * [`point`:`node_id_1`] + * * [`point`:`node_id_2`] + * * [`point`:`bitcoin_key_1`] + * * [`point`:`bitcoin_key_2`] + */ + /* 2 byte msg type + 256 byte signatures */ + int offset = 258; + struct sha256_double hash; + sha256_double(&hash, announcement + offset, + tal_count(announcement) - offset); + + if (!check_signed_hash_nodeid(&hash, node1_sig, node1_id)) { + return tal_fmt(ctx, + "Bad node_signature_1 %s hash %s" + " on channel_announcement %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + node1_sig), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, announcement)); + } + if (!check_signed_hash_nodeid(&hash, node2_sig, node2_id)) { + return tal_fmt(ctx, + "Bad node_signature_2 %s hash %s" + " on channel_announcement %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + node2_sig), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, announcement)); + } + if (!check_signed_hash(&hash, bitcoin1_sig, bitcoin1_key)) { + return tal_fmt(ctx, + "Bad bitcoin_signature_1 %s hash %s" + " on channel_announcement %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + bitcoin1_sig), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, announcement)); + } + if (!check_signed_hash(&hash, bitcoin2_sig, bitcoin2_key)) { + return tal_fmt(ctx, + "Bad bitcoin_signature_2 %s hash %s" + " on channel_announcement %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + bitcoin2_sig), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, announcement)); + } + return NULL; +} + +/* Returns warning msg if signature wrong, else NULL */ +const char *sigcheck_node_announcement(const tal_t *ctx, + const struct node_id *node_id, + const secp256k1_ecdsa_signature *signature, + const u8 *node_announcement) +{ + /* BOLT #7: + * + * 1. type: 257 (`node_announcement`) + * 2. data: + * * [`signature`:`signature`] + * * [`u16`:`flen`] + * * [`flen*byte`:`features`] + * * [`u32`:`timestamp`] + * * [`point`:`node_id`] + * * [`3*byte`:`rgb_color`] + * * [`32*byte`:`alias`] + * * [`u16`:`addrlen`] + * * [`addrlen*byte`:`addresses`] + */ + /* 2 byte msg type + 64 byte signatures */ + int offset = 66; + struct sha256_double hash; + + sha256_double(&hash, node_announcement + offset, tal_count(node_announcement) - offset); + /* If node_id is invalid, it fails here */ + if (!check_signed_hash_nodeid(&hash, signature, node_id)) { + /* BOLT #7: + * + * - if `signature` is not a valid signature, using + * `node_id` of the double-SHA256 of the entire + * message following the `signature` field + * (including unknown fields following + * `fee_proportional_millionths`): + * - SHOULD send a `warning` and close the connection. + * - MUST NOT process the message further. + */ + return tal_fmt(ctx, + "Bad signature for %s hash %s" + " on node_announcement %s", + type_to_string(tmpctx, + secp256k1_ecdsa_signature, + signature), + type_to_string(tmpctx, + struct sha256_double, + &hash), + tal_hex(tmpctx, node_announcement)); + } + + return NULL; +} diff --git a/gossipd/sigcheck.h b/gossipd/sigcheck.h new file mode 100644 index 000000000..ac15b831e --- /dev/null +++ b/gossipd/sigcheck.h @@ -0,0 +1,29 @@ +#ifndef LIGHTNING_GOSSIPD_SIGCHECK_H +#define LIGHTNING_GOSSIPD_SIGCHECK_H +#include "config.h" +#include + +/* Returns error msg if signature wrong, else NULL */ +const char *sigcheck_channel_update(const tal_t *ctx, + const struct node_id *node_id, + const secp256k1_ecdsa_signature *node_sig, + const u8 *update); + +/* Returns error msg if signature wrong, else NULL */ +const char *sigcheck_channel_announcement(const tal_t *ctx, + const struct node_id *node1_id, + const struct node_id *node2_id, + const struct pubkey *bitcoin1_key, + const struct pubkey *bitcoin2_key, + const secp256k1_ecdsa_signature *node1_sig, + const secp256k1_ecdsa_signature *node2_sig, + const secp256k1_ecdsa_signature *bitcoin1_sig, + const secp256k1_ecdsa_signature *bitcoin2_sig, + const u8 *announcement); + +/* Returns error msg if signature wrong, else NULL */ +const char *sigcheck_node_announcement(const tal_t *ctx, + const struct node_id *node_id, + const secp256k1_ecdsa_signature *node_sig, + const u8 *node_announcement); +#endif /* LIGHTNING_GOSSIPD_SIGCHECK_H */ diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index 77184b16b..284d1d21b 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -29,7 +29,8 @@ In particular, we set feature bit 19. The spec says we should set feature bit 1 #include "config.h" #include "../common/wire_error.c" -#include "../routing.c" +#include "../sigcheck.c" +#include #include #include #include @@ -54,84 +55,13 @@ bool blinding_next_pubkey(const struct pubkey *pk UNNEEDED, const struct sha256 *h UNNEEDED, struct pubkey *next UNNEEDED) { fprintf(stderr, "blinding_next_pubkey called!\n"); abort(); } -/* Generated stub for daemon_conn_send */ -void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED) -{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); } -/* Generated stub for get_cupdate_parts */ -void get_cupdate_parts(const u8 *channel_update UNNEEDED, - const u8 *parts[2] UNNEEDED, - size_t sizes[2]) -{ fprintf(stderr, "get_cupdate_parts called!\n"); abort(); } -/* Generated stub for gossip_store_add */ -u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED, - u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED, - const u8 *addendum UNNEEDED) -{ fprintf(stderr, "gossip_store_add called!\n"); abort(); } -/* Generated stub for gossip_store_delete */ -void gossip_store_delete(struct gossip_store *gs UNNEEDED, - struct broadcastable *bcast UNNEEDED, - int type UNNEEDED) -{ fprintf(stderr, "gossip_store_delete called!\n"); abort(); } -/* Generated stub for gossip_store_get */ -const u8 *gossip_store_get(const tal_t *ctx UNNEEDED, - struct gossip_store *gs UNNEEDED, - u64 offset UNNEEDED) -{ fprintf(stderr, "gossip_store_get called!\n"); abort(); } -/* Generated stub for gossip_store_mark_channel_deleted */ -void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED, - const struct short_channel_id *scid UNNEEDED) -{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); } -/* Generated stub for gossip_store_mark_dying */ -void gossip_store_mark_dying(struct gossip_store *gs UNNEEDED, - const struct broadcastable *bcast UNNEEDED, - int type UNNEEDED) -{ fprintf(stderr, "gossip_store_mark_dying called!\n"); abort(); } -/* Generated stub for gossip_store_new */ -struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED) -{ fprintf(stderr, "gossip_store_new called!\n"); abort(); } -/* Generated stub for in_txout_failures */ -bool in_txout_failures(struct txout_failures *txf UNNEEDED, - const struct short_channel_id scid UNNEEDED) -{ fprintf(stderr, "in_txout_failures called!\n"); abort(); } -/* Generated stub for memleak_add_helper_ */ -void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, - const tal_t *)){ } -/* Generated stub for memleak_scan_htable */ -void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) -{ fprintf(stderr, "memleak_scan_htable called!\n"); abort(); } -/* Generated stub for memleak_scan_intmap_ */ -void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) -{ fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); } -/* Generated stub for notleak_ */ -void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED) -{ fprintf(stderr, "notleak_ called!\n"); abort(); } -/* Generated stub for peer_supplied_good_gossip */ -void peer_supplied_good_gossip(struct daemon *daemon UNNEEDED, - const struct node_id *source_peer UNNEEDED, - size_t amount UNNEEDED) -{ fprintf(stderr, "peer_supplied_good_gossip called!\n"); abort(); } -/* Generated stub for status_fmt */ -void status_fmt(enum log_level level UNNEEDED, - const struct node_id *peer UNNEEDED, - const char *fmt UNNEEDED, ...) - -{ fprintf(stderr, "status_fmt called!\n"); abort(); } -/* Generated stub for towire_gossipd_remote_channel_update */ -u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct node_id *source_node UNNEEDED, const struct peer_update *peer_update UNNEEDED) -{ fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); } -/* Generated stub for txout_failures_add */ -void txout_failures_add(struct txout_failures *txf UNNEEDED, - const struct short_channel_id scid UNNEEDED) -{ fprintf(stderr, "txout_failures_add called!\n"); abort(); } -/* Generated stub for txout_failures_new */ -struct txout_failures *txout_failures_new(const tal_t *ctx UNNEEDED, struct daemon *daemon UNNEEDED) -{ fprintf(stderr, "txout_failures_new called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ int main(int argc, char *argv[]) { struct bitcoin_blkid chain_hash; - u8 *features, *err; + u8 *features; + const char *err; secp256k1_ecdsa_signature node_signature_1, node_signature_2; secp256k1_ecdsa_signature bitcoin_signature_1, bitcoin_signature_2; struct short_channel_id short_channel_id; @@ -156,16 +86,15 @@ int main(int argc, char *argv[]) &bitcoin_key_2)) abort(); - err = check_channel_announcement(cannounce, - &node_id_1, &node_id_2, - &bitcoin_key_1, &bitcoin_key_2, - &node_signature_1, &node_signature_2, - &bitcoin_signature_1, - &bitcoin_signature_2, - cannounce); + err = sigcheck_channel_announcement(cannounce, + &node_id_1, &node_id_2, + &bitcoin_key_1, &bitcoin_key_2, + &node_signature_1, &node_signature_2, + &bitcoin_signature_1, + &bitcoin_signature_2, + cannounce); assert(err); - assert(memmem(err, tal_bytelen(err), - "Bad node_signature_1", strlen("Bad node_signature_1"))); + assert(strstr(err, "Bad node_signature_1")); /* Turns out they didn't include the feature bit at all. */ cannounce = towire_channel_announcement(tmpctx, @@ -180,16 +109,15 @@ int main(int argc, char *argv[]) &node_id_2, &bitcoin_key_1, &bitcoin_key_2); - err = check_channel_announcement(cannounce, - &node_id_1, &node_id_2, - &bitcoin_key_1, &bitcoin_key_2, - &node_signature_1, &node_signature_2, - &bitcoin_signature_1, - &bitcoin_signature_2, - cannounce); + err = sigcheck_channel_announcement(cannounce, + &node_id_1, &node_id_2, + &bitcoin_key_1, &bitcoin_key_2, + &node_signature_1, &node_signature_2, + &bitcoin_signature_1, + &bitcoin_signature_2, + cannounce); assert(err); - assert(memmem(err, tal_bytelen(err), - "Bad node_signature_2", strlen("Bad node_signature_2"))); + assert(strstr(err, "Bad node_signature_2")); common_shutdown(); return 0;