Return NULL if the codex32 is invalid */
| 303 | |
| 304 | /* Return NULL if the codex32 is invalid */ |
| 305 | struct codex32 *codex32_decode(const tal_t *ctx, |
| 306 | const char *hrp, |
| 307 | const char *codex32str, |
| 308 | char **fail) |
| 309 | { |
| 310 | struct codex32 *parts = tal(ctx, struct codex32); |
| 311 | const char *sep, *codex_datastr; |
| 312 | char threshold_char; |
| 313 | size_t maxlen; |
| 314 | const struct checksum_engine *csum_engine; |
| 315 | |
| 316 | /* Lowercase it all, iff it's all uppercase. */ |
| 317 | codex32str = bech32_case_fixup(tmpctx, codex32str, &sep); |
| 318 | if (!codex32str) { |
| 319 | *fail = tal_fmt(ctx, "Not a valid bech32 string!"); |
| 320 | return tal_free(parts); |
| 321 | } |
| 322 | |
| 323 | if (!sep) { |
| 324 | *fail = tal_fmt(ctx, "Separator doesn't exist!"); |
| 325 | return tal_free(parts); |
| 326 | } |
| 327 | |
| 328 | parts->hrp = tal_strndup(parts, codex32str, sep - codex32str); |
| 329 | if (hrp && !streq(parts->hrp, hrp)) { |
| 330 | *fail = tal_fmt(ctx, "Invalid hrp %s!", parts->hrp); |
| 331 | return tal_free(parts); |
| 332 | } |
| 333 | |
| 334 | codex_datastr = sep + 1; |
| 335 | maxlen = strlen(codex_datastr); |
| 336 | |
| 337 | /* If it's short, use short checksum engine. If it's invalid, |
| 338 | * use short checksum and we'll fail when payload is too long. */ |
| 339 | csum_engine = &initial_engine_csum[maxlen >= 96]; |
| 340 | if (!checksum_verify(parts->hrp, codex_datastr, csum_engine)) { |
| 341 | *fail = tal_fmt(ctx, "Invalid checksum!"); |
| 342 | return tal_free(parts); |
| 343 | } |
| 344 | |
| 345 | /* Pull fixed parts and discard checksum */ |
| 346 | if (!pull_chars(&threshold_char, 1, &codex_datastr, &maxlen) |
| 347 | || !pull_chars(parts->id, ARRAY_SIZE(parts->id) - 1, &codex_datastr, &maxlen) |
| 348 | || !pull_chars(&parts->share_idx, 1, &codex_datastr, &maxlen) |
| 349 | || !trim_chars(csum_engine->len, &codex_datastr, &maxlen)) { |
| 350 | *fail = tal_fmt(ctx, "Too short!"); |
| 351 | return tal_free(parts); |
| 352 | } |
| 353 | parts->id[ARRAY_SIZE(parts->id)-1] = 0; |
| 354 | /* Is payload too long for this checksum? */ |
| 355 | if (maxlen > csum_engine->max_payload_len) { |
| 356 | *fail = tal_fmt(ctx, "Invalid length!"); |
| 357 | return tal_free(parts); |
| 358 | } |
| 359 | |
| 360 | parts->payload = decode_payload(parts, codex_datastr, maxlen); |
| 361 | if (!parts->payload) { |
| 362 | *fail = tal_fmt(ctx, "Invalid payload!"); |