core+legacy: make path checks more benevolent (#84)

Non-existing BIP-48 is causing mess among implementations
pull/106/head
Pavol Rusnak 5 years ago committed by GitHub
parent 8c9f74d16c
commit def96032d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -204,7 +204,7 @@ def validate_full_path(
See docs/coins for what paths are allowed. Please note that this is not See docs/coins for what paths are allowed. Please note that this is not
a comprehensive check, some nuances are omitted for simplification. a comprehensive check, some nuances are omitted for simplification.
""" """
if len(path) != 5: if len(path) not in (4, 5, 6):
return False return False
if not validate_purpose(path[0], coin): if not validate_purpose(path[0], coin):
@ -214,21 +214,29 @@ def validate_full_path(
): ):
return False return False
if path[1] != coin.slip44 | HARDENED: if path[1] > 20 and path[1] != coin.slip44 | HARDENED:
return False return False
if path[2] < HARDENED or path[2] > 20 | HARDENED: if (path[2] > 20 and path[2] < HARDENED) or path[2] > 20 | HARDENED:
return False
if path[3] not in (0, 1, 0 | HARDENED, 1 | HARDENED, 2 | HARDENED):
return False return False
if path[3] not in [0, 1]: if len(path) > 4 and path[4] > 1000000:
return False return False
if path[4] > 1000000: if len(path) > 5 and path[5] > 1000000:
return False return False
return True return True
def validate_purpose(purpose: int, coin: CoinInfo) -> bool: def validate_purpose(purpose: int, coin: CoinInfo) -> bool:
if purpose not in (44 | HARDENED, 48 | HARDENED, 49 | HARDENED, 84 | HARDENED): if purpose not in (
44 | HARDENED,
45 | HARDENED,
48 | HARDENED,
49 | HARDENED,
84 | HARDENED,
):
return False return False
if not coin.segwit and purpose not in (44 | HARDENED, 48 | HARDENED): if not coin.segwit and purpose not in (44 | HARDENED, 45 | HARDENED, 48 | HARDENED):
return False return False
return True return True
@ -239,21 +247,23 @@ def validate_purpose_against_script_type(
""" """
Validates purpose against provided input's script type: Validates purpose against provided input's script type:
- 44 for spending address (script_type == SPENDADDRESS) - 44 for spending address (script_type == SPENDADDRESS)
- 48 for multisig (script_type == SPENDMULTISIG) - 45, 48 for multisig (script_type == SPENDMULTISIG)
- 49 for p2sh-segwit spend (script_type == SPENDP2SHWITNESS) - 49 for p2wsh-nested-in-p2sh spend (script_type == SPENDP2SHWITNESS)
- 84 for native segwit spend (script_type == SPENDWITNESS) - 84 for p2wsh native segwit spend (script_type == SPENDWITNESS)
""" """
if purpose == 44 | HARDENED and script_type != InputScriptType.SPENDADDRESS: if purpose == 44 | HARDENED and script_type != InputScriptType.SPENDADDRESS:
return False return False
if purpose == 48 | HARDENED and script_type != InputScriptType.SPENDMULTISIG: if purpose == 45 | HARDENED and script_type != InputScriptType.SPENDMULTISIG:
return False return False
if ( # p2wsh-nested-in-p2sh if purpose == 48 | HARDENED and script_type not in (
purpose == 49 | HARDENED and script_type != InputScriptType.SPENDP2SHWITNESS InputScriptType.SPENDMULTISIG,
InputScriptType.SPENDP2SHWITNESS,
InputScriptType.SPENDWITNESS,
): ):
return False return False
if ( # p2wsh if purpose == 49 | HARDENED and script_type != InputScriptType.SPENDP2SHWITNESS:
purpose == 84 | HARDENED and script_type != InputScriptType.SPENDWITNESS return False
): if purpose == 84 | HARDENED and script_type != InputScriptType.SPENDWITNESS:
return False return False
return True return True

@ -147,12 +147,15 @@ static bool path_mismatched(const CoinInfo *coin, const GetAddress *msg) {
// m/48' - BIP48 Copay Multisig P2SH // m/48' - BIP48 Copay Multisig P2SH
// m / purpose' / coin_type' / account' / change / address_index // m / purpose' / coin_type' / account' / change / address_index
// Electrum:
// m / purpose' / coin_type' / account' / type' / change / address_index
if (msg->address_n[0] == (0x80000000 + 48)) { if (msg->address_n[0] == (0x80000000 + 48)) {
mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG); mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG) &&
mismatch |= (msg->address_n_count != 5); (msg->script_type != InputScriptType_SPENDP2SHWITNESS) &&
(msg->script_type != InputScriptType_SPENDWITNESS);
mismatch |= (msg->address_n_count != 5) && (msg->address_n_count != 6);
mismatch |= (msg->address_n[1] != coin->coin_type); mismatch |= (msg->address_n[1] != coin->coin_type);
mismatch |= (msg->address_n[2] & 0x80000000) == 0; mismatch |= (msg->address_n[2] & 0x80000000) == 0;
mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000;
mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000;
return mismatch; return mismatch;
} }

Loading…
Cancel
Save