rewrite derivation paths on file and card imports, compare multisig keystore derivations with rewritten paths

This commit is contained in:
Craig Raw 2024-08-22 11:07:29 +02:00
parent af89be96e5
commit 95b1aa8e48
8 changed files with 13 additions and 12 deletions

2
drongo

@ -1 +1 @@
Subproject commit 0e084782941f514613a15967c00476e21e038e1d Subproject commit 87b5f992d085efac64e7466af4906f9d1691fc8a

View file

@ -60,7 +60,7 @@ public class CaravanMultisig implements WalletImport, WalletExport {
} }
try { try {
keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, extKey.bip32Path)); keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, extKey.bip32Path, true));
} catch(NumberFormatException e) { } catch(NumberFormatException e) {
keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, scriptType.getDefaultDerivationPath())); keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, scriptType.getDefaultDerivationPath()));
} }

View file

@ -48,7 +48,7 @@ public class CoboVaultSinglesig implements KeystoreFileImport, WalletImport {
keystore.setLabel(getName()); keystore.setLabel(getName());
keystore.setSource(KeystoreSource.HW_AIRGAPPED); keystore.setSource(KeystoreSource.HW_AIRGAPPED);
keystore.setWalletModel(WalletModel.COBO_VAULT); keystore.setWalletModel(WalletModel.COBO_VAULT);
keystore.setKeyDerivation(new KeyDerivation(coboKeystore.MasterFingerprint.toLowerCase(Locale.ROOT), "m/" + coboKeystore.AccountKeyPath)); keystore.setKeyDerivation(new KeyDerivation(coboKeystore.MasterFingerprint.toLowerCase(Locale.ROOT), "m/" + coboKeystore.AccountKeyPath, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(coboKeystore.ExtPubKey)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(coboKeystore.ExtPubKey));
ExtendedKey.Header header = ExtendedKey.Header.fromExtendedKey(coboKeystore.ExtPubKey); ExtendedKey.Header header = ExtendedKey.Header.fromExtendedKey(coboKeystore.ExtPubKey);

View file

@ -71,16 +71,16 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle
if(header.getDefaultScriptType() != scriptType) { if(header.getDefaultScriptType() != scriptType) {
throw new ImportException("This wallet's script type (" + scriptType + ") does not match the " + getName() + " script type (" + header.getDefaultScriptType() + ")"); throw new ImportException("This wallet's script type (" + scriptType + ") does not match the " + getName() + " script type (" + header.getDefaultScriptType() + ")");
} }
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.path)); keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.path, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.xpub)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.xpub));
} else if(scriptType.equals(ScriptType.P2SH)) { } else if(scriptType.equals(ScriptType.P2SH)) {
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2sh_deriv)); keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2sh_deriv, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2sh)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2sh));
} else if(scriptType.equals(ScriptType.P2SH_P2WSH)) { } else if(scriptType.equals(ScriptType.P2SH_P2WSH)) {
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_p2sh_deriv != null ? cck.p2wsh_p2sh_deriv : cck.p2sh_p2wsh_deriv)); keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_p2sh_deriv != null ? cck.p2wsh_p2sh_deriv : cck.p2sh_p2wsh_deriv, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2wsh_p2sh != null ? cck.p2wsh_p2sh : cck.p2sh_p2wsh)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2wsh_p2sh != null ? cck.p2wsh_p2sh : cck.p2sh_p2wsh));
} else if(scriptType.equals(ScriptType.P2WSH)) { } else if(scriptType.equals(ScriptType.P2WSH)) {
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_deriv)); keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_deriv, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2wsh)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(cck.p2wsh));
} else { } else {
throw new ImportException("Correct derivation not found for script type: " + scriptType); throw new ImportException("Correct derivation not found for script type: " + scriptType);
@ -157,7 +157,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle
Keystore keystore = new Keystore("Coldcard"); Keystore keystore = new Keystore("Coldcard");
keystore.setSource(KeystoreSource.HW_AIRGAPPED); keystore.setSource(KeystoreSource.HW_AIRGAPPED);
keystore.setWalletModel(WalletModel.COLDCARD); keystore.setWalletModel(WalletModel.COLDCARD);
keystore.setKeyDerivation(new KeyDerivation(key, derivation)); keystore.setKeyDerivation(new KeyDerivation(key, derivation, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(value)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(value));
wallet.makeLabelsUnique(keystore); wallet.makeLabelsUnique(keystore);
wallet.getKeystores().add(keystore); wallet.getKeystores().add(keystore);

View file

@ -78,7 +78,7 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport {
keystore.setLabel(getName()); keystore.setLabel(getName());
keystore.setSource(KeystoreSource.HW_AIRGAPPED); keystore.setSource(KeystoreSource.HW_AIRGAPPED);
keystore.setWalletModel(WalletModel.COLDCARD); keystore.setWalletModel(WalletModel.COLDCARD);
keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, ck.deriv)); keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, ck.deriv, true));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(ck.xpub)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(ck.xpub));
return keystore; return keystore;

View file

@ -186,7 +186,7 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport
keystore.setWalletModel(WalletModel.ELECTRUM); keystore.setWalletModel(WalletModel.ELECTRUM);
} }
keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, derivationPath)); keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, derivationPath, true));
keystore.setExtendedPublicKey(xPub); keystore.setExtendedPublicKey(xPub);
keystore.setLabel(ek.label != null ? ek.label : "Electrum"); keystore.setLabel(ek.label != null ? ek.label : "Electrum");
if(keystore.getLabel().length() > Keystore.MAX_LABEL_LENGTH) { if(keystore.getLabel().length() > Keystore.MAX_LABEL_LENGTH) {

View file

@ -142,7 +142,7 @@ public class SatoCardApi extends CardApi {
String masterXpub = this.cardProtocol.cardBip32GetXpub("m", xtype); String masterXpub = this.cardProtocol.cardBip32GetXpub("m", xtype);
ExtendedKey masterExtendedKey = ExtendedKey.fromDescriptor(masterXpub); ExtendedKey masterExtendedKey = ExtendedKey.fromDescriptor(masterXpub);
String masterFingerprint = Utils.bytesToHex(masterExtendedKey.getKey().getFingerprint()); String masterFingerprint = Utils.bytesToHex(masterExtendedKey.getKey().getFingerprint());
KeyDerivation keyDerivation = new KeyDerivation(masterFingerprint, keyDerivationString); KeyDerivation keyDerivation = new KeyDerivation(masterFingerprint, keyDerivationString, true);
Keystore keystore = new Keystore(); Keystore keystore = new Keystore();
keystore.setLabel(WalletModel.SATOCHIP.toDisplayString()); keystore.setLabel(WalletModel.SATOCHIP.toDisplayString());

View file

@ -41,8 +41,9 @@ public abstract class WalletFormController extends BaseController {
protected boolean isSingleDerivationPath() { protected boolean isSingleDerivationPath() {
KeyDerivation firstDerivation = getWalletForm().getWallet().getKeystores().get(0).getKeyDerivation(); KeyDerivation firstDerivation = getWalletForm().getWallet().getKeystores().get(0).getKeyDerivation();
String firstDerivationPath = KeyDerivation.writePath(firstDerivation.getDerivation());
for(Keystore keystore : getWalletForm().getWallet().getKeystores()) { for(Keystore keystore : getWalletForm().getWallet().getKeystores()) {
if(!keystore.getKeyDerivation().getDerivationPath().equals(firstDerivation.getDerivationPath())) { if(!KeyDerivation.writePath(keystore.getKeyDerivation().getDerivation()).equals(firstDerivationPath)) {
return false; return false;
} }
} }