u8 *tal_hexdata(const tal_t *ctx, const void *str, size_t len) { u8 *data = tal_arr(ctx, u8, hex_data_size(len)); if (!hex_decode(str, len, data, hex_data_size(len))) return NULL; return data; }
struct bitcoin_tx *bitcoin_tx_from_hex(const tal_t *ctx, const char *hex, size_t hexlen) { const char *end; u8 *linear_tx; const u8 *p; struct bitcoin_tx *tx; size_t len; end = memchr(hex, '\n', hexlen); if (!end) end = hex + hexlen; len = hex_data_size(end - hex); p = linear_tx = tal_arr(ctx, u8, len); if (!hex_decode(hex, end - hex, linear_tx, len)) goto fail; tx = pull_bitcoin_tx(ctx, &p, &len); if (!tx) goto fail; if (len) goto fail_free_tx; tal_free(linear_tx); return tx; fail_free_tx: tal_free(tx); fail: tal_free(linear_tx); return NULL; }
/* Encoding is <blockhdr> <varint-num-txs> <tx>... */ struct bitcoin_block *bitcoin_block_from_hex(const tal_t *ctx, const char *hex, size_t hexlen) { struct bitcoin_block *b; u8 *linear_tx; const u8 *p; size_t len, i, num; if (hexlen && hex[hexlen-1] == '\n') hexlen--; /* Set up the block for success. */ b = tal(ctx, struct bitcoin_block); /* De-hex the array. */ len = hex_data_size(hexlen); p = linear_tx = tal_arr(ctx, u8, len); if (!hex_decode(hex, hexlen, linear_tx, len)) return tal_free(b); pull(&p, &len, &b->hdr, sizeof(b->hdr)); num = pull_varint(&p, &len); b->tx = tal_arr(b, struct bitcoin_tx *, num); for (i = 0; i < num; i++) b->tx[i] = pull_bitcoin_tx(b->tx, &p, &len); /* We should end up not overrunning, nor have extra */ if (!p || len) return tal_free(b); tal_free(linear_tx); return b; }
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) { u8 *result; size_t hexlen, rawlen; hexlen = tok->end - tok->start; rawlen = hex_data_size(hexlen); result = tal_arr(ctx, u8, rawlen); if (!hex_decode(buffer + tok->start, hexlen, result, rawlen)) return tal_free(result); return result; }
int main(void) { const char teststr[] = "0123456789abcdefABCDEF"; const char bad_teststr[] = "0123456789abcdefABCDEF1O"; const unsigned char testdata[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xAB, 0xCD, 0xEF }; unsigned char data[11]; char str[23]; size_t i; plan_tests(10 + sizeof(str)); ok1(hex_str_size(sizeof(testdata)) == sizeof(teststr)); /* This gives right result with or without nul included */ ok1(hex_data_size(strlen(teststr)) == sizeof(testdata)); ok1(hex_data_size(sizeof(teststr)) == sizeof(testdata)); ok1(hex_decode(teststr, strlen(teststr), data, sizeof(data))); ok1(memcmp(data, testdata, sizeof(testdata)) == 0); ok1(hex_encode(testdata, sizeof(testdata), str, sizeof(str))); ok1(strcmp(str, "0123456789abcdefabcdef") == 0); /* Bad char */ ok1(!hex_decode(bad_teststr, strlen(bad_teststr), data, sizeof(data))); /* Bad hex string len */ ok1(!hex_decode(teststr, strlen(teststr) - 1, data, sizeof(data))); /* Bad buffer len */ ok1(!hex_decode(teststr, strlen(teststr), data, sizeof(data) - 1)); /* Bad deststring size. */ for (i = 1; i <= sizeof(str); i++) ok1(!hex_encode(testdata, sizeof(testdata), str, sizeof(str)-i)); /* This exits depending on whether all tests passed */ return exit_status(); }
static void parse_anchor_input(const char *spec, struct input *in) { const char *slash; char *end; long l; bool testnet; slash = strchr(spec, '/'); if (!slash) errx(1, "Expected / in <txid>/<num>/<satoshis>/<hexscript>/<privkey>"); if (!bitcoin_txid_from_hex(spec, slash - spec, &in->in.txid)) errx(1, "Expected 256-bit hex txid before /"); in->in.index = l = strtol(slash + 1, &end, 10); if (end == slash + 1 || *end != '/' || (int64_t)in->in.index != (int64_t)l) errx(1, "Expected <outputnum> after /"); slash = end; in->in.input_amount = l = strtol(slash + 1, &end, 10); if (end == slash + 1 || *end != '/' || (int64_t)in->in.input_amount != (int64_t)l) errx(1, "Expected <satoshis> after second /"); slash = end; end = (char *)slash + 1 + strcspn(slash + 1, "/"); in->in.script_length = hex_data_size(end - (slash + 1)); in->in.script = tal_arr(in, u8, in->in.script_length); if (!hex_decode(slash + 1, end - (slash + 1), in->in.script, in->in.script_length)) errx(1, "Expected hex string after third /"); if (*end != '/') errx(1, "Expected / after hexscript"); if (!key_from_base58(end+1, strlen(end + 1), &testnet, &in->privkey, &in->pubkey)) errx(1, "Invalid private key '%s'", end+1); if (!testnet) errx(1, "Private key '%s' not on testnet!", end+1); }
static raw_iblt *read_iblt(std::istream &in, size_t *ibltslices, u64 *seed) { std::string ibltstr; // If they choose not to IBLT encode. if (in.peek() != 'i') return NULL; std::getline(in, ibltstr, ','); if (ibltstr != "iblt") throw std::runtime_error("Bad iblt line"); std::string iblthex; std::getline(in, iblthex); if (!in) throw std::runtime_error("Bad iblt hex line"); size_t ibltsize = hex_data_size(iblthex.size()); u8 data[ibltsize]; if (!hex_decode(iblthex.c_str(), iblthex.size(), data, sizeof(data))) throw std::runtime_error("Bad iblt hex"); const u8 *p = data; size_t len = sizeof(data); *ibltslices = pull_varint(&p, &len); if (!p) throw std::runtime_error("Bad iblt size"); if (len < 16) throw std::runtime_error("Bad iblt seed"); memcpy(seed, p, sizeof(*seed)); p += 16; len -= 16; raw_iblt *riblt = new raw_iblt(*ibltslices); if (!riblt->read(p, len)) throw std::runtime_error("Bad iblt"); return riblt; }
/* Run an HMAC using the key above on the library binary data. * Returns true on success and false on error. */ static unsigned check_binary_integrity(const char* libname, const char* symbol) { int ret; unsigned prev; char mac_file[GNUTLS_PATH_MAX]; char file[GNUTLS_PATH_MAX]; uint8_t hmac[HMAC_SIZE]; uint8_t new_hmac[HMAC_SIZE]; size_t hmac_size; gnutls_datum_t data; ret = get_library_path(libname, symbol, file, sizeof(file)); if (ret < 0) { _gnutls_debug_log("Could not get path for library %s\n", libname); return 0; } _gnutls_debug_log("Loading: %s\n", file); ret = gnutls_load_file(file, &data); if (ret < 0) { _gnutls_debug_log("Could not load: %s\n", file); return gnutls_assert_val(0); } prev = _gnutls_get_lib_state(); _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = gnutls_hmac_fast(HMAC_ALGO, FIPS_KEY, sizeof(FIPS_KEY)-1, data.data, data.size, new_hmac); _gnutls_switch_lib_state(prev); gnutls_free(data.data); if (ret < 0) return gnutls_assert_val(0); /* now open the .hmac file and compare */ get_hmac_file(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { get_hmac_file2(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { _gnutls_debug_log("Could not open %s for MAC testing: %s\n", mac_file, gnutls_strerror(ret)); return gnutls_assert_val(0); } } hmac_size = hex_data_size(data.size); ret = gnutls_hex_decode(&data, hmac, &hmac_size); gnutls_free(data.data); if (ret < 0) { _gnutls_debug_log("Could not convert hex data to binary for MAC testing for %s.\n", libname); return gnutls_assert_val(0); } if (hmac_size != sizeof(hmac) || memcmp(hmac, new_hmac, sizeof(hmac)) != 0) { _gnutls_debug_log("Calculated MAC for %s does not match\n", libname); return gnutls_assert_val(0); } _gnutls_debug_log("Successfully verified MAC for %s (%s)\n", mac_file, libname); return 1; }