Bugfix: _blkmk_b58check: Check that zero-padding on base58check input matches output
This is needed to properly reject addresses with too many or too few prefix/pad '1's.
This commit is contained in:
12
base58.c
12
base58.c
@@ -83,13 +83,21 @@ bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _blkmk_b58check(void *bin, size_t binsz) {
|
int _blkmk_b58check(void *bin, size_t binsz, const char *base58str) {
|
||||||
unsigned char buf[32];
|
unsigned char buf[32];
|
||||||
unsigned char *binc = bin;
|
unsigned char *binc = bin;
|
||||||
|
unsigned i;
|
||||||
if (!_blkmk_dblsha256(buf, bin, binsz - 4))
|
if (!_blkmk_dblsha256(buf, bin, binsz - 4))
|
||||||
return -2;
|
return -2;
|
||||||
if (memcmp(&binc[binsz - 4], buf, 4))
|
if (memcmp(&binc[binsz - 4], buf, 4))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
|
||||||
|
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
|
||||||
|
{} // Just finding the end of zeros, nothing to do in loop
|
||||||
|
if (binc[i] == '\0' || base58str[i] == '1')
|
||||||
|
return -3;
|
||||||
|
|
||||||
return binc[0];
|
return binc[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +109,7 @@ size_t blkmk_address_to_script(void *out, size_t outsz, const char *addr) {
|
|||||||
|
|
||||||
if (!_blkmk_b58tobin(addrbin, sizeof(addrbin), addr, 0))
|
if (!_blkmk_b58tobin(addrbin, sizeof(addrbin), addr, 0))
|
||||||
return 0;
|
return 0;
|
||||||
addrver = _blkmk_b58check(addrbin, sizeof(addrbin));
|
addrver = _blkmk_b58check(addrbin, sizeof(addrbin), addr);
|
||||||
switch (addrver) {
|
switch (addrver) {
|
||||||
case 0: // Bitcoin pubkey hash
|
case 0: // Bitcoin pubkey hash
|
||||||
case 111: // Testnet pubkey hash
|
case 111: // Testnet pubkey hash
|
||||||
|
|||||||
12
example.c
12
example.c
@@ -13,16 +13,24 @@
|
|||||||
#include "testinput.c"
|
#include "testinput.c"
|
||||||
|
|
||||||
void testb58() {
|
void testb58() {
|
||||||
|
int rv;
|
||||||
|
const char *iaddr = "11Baf75Ferj6A7AoN565gCQj9kGWbDMHfN9";
|
||||||
|
const char *addr = &iaddr[1];
|
||||||
char bufx[26] = {'\xff'};
|
char bufx[26] = {'\xff'};
|
||||||
char *buf = &bufx[1];
|
char *buf = &bufx[1];
|
||||||
if (!_blkmk_b58tobin(buf, 25, "1Baf75Ferj6A7AoN565gCQj9kGWbDMHfN9", 0))
|
if (!_blkmk_b58tobin(buf, 25, addr, 0))
|
||||||
exit(1);
|
exit(1);
|
||||||
if (bufx[0] != '\xff')
|
if (bufx[0] != '\xff')
|
||||||
exit(2);
|
exit(2);
|
||||||
char cbuf[51];
|
char cbuf[51];
|
||||||
_blkmk_bin2hex(cbuf, buf, 25);
|
_blkmk_bin2hex(cbuf, buf, 25);
|
||||||
printf("Base58 raw data: %s\n", cbuf);
|
printf("Base58 raw data: %s\n", cbuf);
|
||||||
printf("Base58 check: %d\n", _blkmk_b58check(buf, 25));
|
assert((rv = _blkmk_b58check(buf, 25, addr)) == 0);
|
||||||
|
printf("Base58 check: %d\n", rv);
|
||||||
|
assert((rv = _blkmk_b58check(buf, 25, &addr[1])) < 0);
|
||||||
|
printf("Base58 check (invalid/ unpadded): %d\n", rv);
|
||||||
|
assert((rv = _blkmk_b58check(buf, 25, iaddr)) < 0);
|
||||||
|
printf("Base58 check (invalid/extra padded): %d\n", rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ extern bool _blkmk_hex2bin(void *o, const char *x, size_t len);
|
|||||||
|
|
||||||
// base58.c
|
// base58.c
|
||||||
extern bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz);
|
extern bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz);
|
||||||
extern int _blkmk_b58check(void *bin, size_t binsz);
|
extern int _blkmk_b58check(void *bin, size_t binsz, const char *b58);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user