1 #include <common/bech32.h>
2 #include <common/json_command.h>
3 #include <common/json_helpers.h>
4 #include <common/json_tok.h>
5 #include <common/param.h>
6 #include <errno.h>
7 #include <hsmd/hsmd_wiregen.h>
8 #include <lightningd/json.h>
9 #include <lightningd/plugin.h>
10 #include <wire/wire_sync.h>
11
12 /* These tables copied from zbase32 src:
13 * copyright 2002-2007 Zooko "Zooko" Wilcox-O'Hearn
14 * mailto:zooko@zooko.com
15 *
16 * Permission is hereby granted to any person obtaining a copy of this work to
17 * deal in this work without restriction (including the rights to use, modify,
18 * distribute, sublicense, and/or sell copies).
19 */
20 static const char*const zbase32_chars="ybndrfg8ejkmcpqxot1uwisza345h769";
21
22 /* revchars: index into this table with the ASCII value of the char. The result is the value of that quintet. */
23 static const u8 zbase32_revchars[]={ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 25, 26, 27, 30, 29, 7, 31, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 24, 1, 12, 3, 8, 5, 6, 28, 21, 9, 10, 255, 11, 2, 16, 13, 14, 4, 22, 17, 19, 255, 20, 15, 0, 23, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, };
24
to_zbase32(const tal_t * ctx,const u8 * msg,size_t srclen)25 static const char *to_zbase32(const tal_t *ctx, const u8 *msg, size_t srclen)
26 {
27 size_t outlen;
28 char *out = tal_arr(ctx, char, (srclen * 8 + 4) / 5 + 1);
29
30 outlen = 0;
31 if (!bech32_convert_bits((uint8_t *)out, &outlen, 5, msg, srclen, 8, true))
32 return tal_free(out);
33 assert(outlen < tal_bytelen(out));
34 for (size_t i = 0; i < outlen; i++)
35 out[i] = zbase32_chars[(unsigned)out[i]];
36 out[outlen] = '\0';
37 return out;
38 }
39
from_zbase32(const tal_t * ctx,const char * msg)40 static const u8 *from_zbase32(const tal_t *ctx, const char *msg)
41 {
42 u5 *u5arr;
43 u8 *u8arr;
44 size_t len;
45
46 u5arr = tal_arr(tmpctx, u5, strlen(msg));
47 for (size_t i = 0; i < tal_bytelen(u5arr); i++) {
48 u5arr[i] = zbase32_revchars[(unsigned char)msg[i]];
49 if (u5arr[i] > 31)
50 return NULL;
51 }
52
53 u8arr = tal_arr(ctx, u8, (tal_bytelen(u5arr) * 5 + 7) / 8);
54 len = 0;
55 if (!bech32_convert_bits(u8arr, &len, 8,
56 u5arr, tal_bytelen(u5arr), 5, false))
57 return tal_free(u8arr);
58 assert(len == tal_bytelen(u8arr));
59 return u8arr;
60 }
61
json_signmessage(struct command * cmd,const char * buffer,const jsmntok_t * obj UNNEEDED,const jsmntok_t * params)62 static struct command_result *json_signmessage(struct command *cmd,
63 const char *buffer,
64 const jsmntok_t *obj UNNEEDED,
65 const jsmntok_t *params)
66 {
67 const char *message;
68 secp256k1_ecdsa_recoverable_signature rsig;
69 struct json_stream *response;
70 u8 sig[65], *msg;
71 int recid;
72
73 if (!param(cmd, buffer, params,
74 p_req("message", param_string, &message),
75 NULL))
76 return command_param_failed();
77
78 if (strlen(message) > 65535)
79 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
80 "Message must be < 64k");
81
82 msg = towire_hsmd_sign_message(NULL,
83 tal_dup_arr(tmpctx, u8, (u8 *)message,
84 strlen(message), 0));
85 if (!wire_sync_write(cmd->ld->hsm_fd, take(msg)))
86 fatal("Could not write to HSM: %s", strerror(errno));
87
88 msg = wire_sync_read(tmpctx, cmd->ld->hsm_fd);
89 if (!fromwire_hsmd_sign_message_reply(msg, &rsig))
90 fatal("HSM gave bad hsm_sign_message_reply %s",
91 tal_hex(msg, msg));
92
93 secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_ctx,
94 sig+1, &recid,
95 &rsig);
96 response = json_stream_success(cmd);
97 json_add_hex(response, "signature", sig+1, sizeof(sig)-1);
98 sig[0] = recid;
99 json_add_hex(response, "recid", sig, 1);
100
101 /* From https://twitter.com/rusty_twit/status/1182102005914800128:
102 * @roasbeef & @bitconner point out that #lnd algo is:
103 * zbase32(SigRec(SHA256(SHA256("Lightning Signed Message:" + msg)))).
104 * zbase32 from https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
105 * and SigRec has first byte 31 + recovery id, followed by 64 byte sig.
106 * #specinatweet */
107 sig[0] += 31;
108 json_add_string(response, "zbase",
109 to_zbase32(response, sig, sizeof(sig)));
110 return command_success(cmd, response);
111 }
112
113 static const struct json_command json_signmessage_cmd = {
114 "signmessage",
115 "utility",
116 json_signmessage,
117 "Create a digital signature of {message}",
118 };
119 AUTODATA(json_command, &json_signmessage_cmd);
120
121 struct command_and_node {
122 struct command *cmd;
123 struct node_id id;
124 };
125
126 /* topology tells us if it's a known node by returning details. */
listnodes_done(const char * buffer,const jsmntok_t * toks,const jsmntok_t * idtok UNUSED,struct command_and_node * can)127 static void listnodes_done(const char *buffer,
128 const jsmntok_t *toks,
129 const jsmntok_t *idtok UNUSED,
130 struct command_and_node *can)
131 {
132 struct json_stream *response;
133 const jsmntok_t *t;
134
135 t = json_get_member(buffer, toks, "result");
136 if (t)
137 t = json_get_member(buffer, t, "nodes");
138
139 response = json_stream_success(can->cmd);
140 json_add_node_id(response, "pubkey", &can->id);
141 json_add_bool(response, "verified", t && t->size == 1);
142 was_pending(command_success(can->cmd, response));
143 }
144
json_checkmessage(struct command * cmd,const char * buffer,const jsmntok_t * obj UNNEEDED,const jsmntok_t * params)145 static struct command_result *json_checkmessage(struct command *cmd,
146 const char *buffer,
147 const jsmntok_t *obj UNNEEDED,
148 const jsmntok_t *params)
149 {
150 struct pubkey *pubkey, reckey;
151 const u8 *u8sig;
152 const char *message, *zb;
153 secp256k1_ecdsa_recoverable_signature rsig;
154 struct sha256_ctx sctx = SHA256_INIT;
155 struct sha256_double shad;
156 struct json_stream *response;
157
158 if (!param(cmd, buffer, params,
159 p_req("message", param_string, &message),
160 p_req("zbase", param_string, &zb),
161 p_opt("pubkey", param_pubkey, &pubkey),
162 NULL))
163 return command_param_failed();
164
165 u8sig = from_zbase32(tmpctx, zb);
166 if (!u8sig)
167 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
168 "zbase is not valid zbase32");
169
170 if (tal_bytelen(u8sig) != 65)
171 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
172 "zbase is too %s",
173 tal_bytelen(u8sig) < 65 ? "short" : "long");
174
175 if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_ctx,
176 &rsig,
177 u8sig + 1,
178 u8sig[0] - 31))
179 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
180 "cannot parse zbase signature");
181
182 sha256_update(&sctx, "Lightning Signed Message:",
183 strlen("Lightning Signed Message:"));
184 sha256_update(&sctx, message, strlen(message));
185 sha256_double_done(&sctx, &shad);
186
187 if (!secp256k1_ecdsa_recover(secp256k1_ctx, &reckey.pubkey, &rsig,
188 shad.sha.u.u8)) {
189 response = json_stream_success(cmd);
190 json_add_bool(response, "verified", false);
191 return command_success(cmd, response);
192 }
193
194 /* If they didn't specify pubkey, we only accept the signature if it's
195 * in the graph (thus, they've signed something with it). This idea
196 * was stolen directly from lnd, thanks @roasbeef.
197 *
198 * FIXME: We could also look through known invoices: AFAICT you can't
199 * make two (different) signed messages with the same recovered key
200 * unless you know the secret key */
201 if (!pubkey) {
202 struct jsonrpc_request *req;
203 struct plugin *plugin;
204 struct command_and_node *can = tal(cmd, struct command_and_node);
205
206 node_id_from_pubkey(&can->id, &reckey);
207 can->cmd = cmd;
208 req = jsonrpc_request_start(cmd, "listnodes",
209 cmd->ld->log,
210 NULL, listnodes_done,
211 can);
212 json_add_node_id(req->stream, "id", &can->id);
213 jsonrpc_request_end(req);
214
215 /* Only works if we have listnodes! */
216 plugin = find_plugin_for_command(cmd->ld, "listnodes");
217 if (plugin) {
218 plugin_request_send(plugin, req);
219 return command_still_pending(cmd);
220 }
221 }
222
223 response = json_stream_success(cmd);
224 json_add_pubkey(response, "pubkey", &reckey);
225 json_add_bool(response, "verified",
226 pubkey && pubkey_eq(pubkey, &reckey));
227 return command_success(cmd, response);
228 }
229
230 static const struct json_command json_checkmessage_cmd = {
231 "checkmessage",
232 "utility",
233 json_checkmessage,
234 "Verify a digital signature {zbase} of {message} signed with {pubkey}",
235 };
236 AUTODATA(json_command, &json_checkmessage_cmd);
237
238