diff --git a/app/src/main/cpp/monerujo.cpp b/app/src/main/cpp/monerujo.cpp index ad369d36..c511be6c 100644 --- a/app/src/main/cpp/monerujo.cpp +++ b/app/src/main/cpp/monerujo.cpp @@ -1310,7 +1310,6 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getFirstTxIdJ(JNIEnv *env, jo return nullptr; } - JNIEXPORT jlong JNICALL Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobject instance) { Bitmonero::PendingTransaction *tx = getHandle(env, instance); @@ -1396,6 +1395,11 @@ Java_com_m2049r_xmrwallet_model_WalletManager_setLogLevel(JNIEnv *env, jclass cl Bitmonero::WalletManagerFactory::setLogLevel(level); } +JNIEXPORT jstring JNICALL +Java_com_m2049r_xmrwallet_model_WalletManager_moneroVersion(JNIEnv *env, jclass clazz) { + return env->NewStringUTF(MONERO_VERSION); +} + // // Ledger Stuff // diff --git a/app/src/main/cpp/monerujo.h b/app/src/main/cpp/monerujo.h index 3be02667..0fb34444 100644 --- a/app/src/main/cpp/monerujo.h +++ b/app/src/main/cpp/monerujo.h @@ -54,6 +54,8 @@ extern "C" { #endif +extern const char* const MONERO_VERSION; // the actual monero core version + // from monero-core crypto/hash-ops.h - avoid #including monero code here enum { HASH_SIZE = 32, diff --git a/app/src/main/java/com/btchip/comm/android/BTChipTransportAndroidHID.java b/app/src/main/java/com/btchip/comm/android/BTChipTransportAndroidHID.java index e4cbd43d..05df9076 100644 --- a/app/src/main/java/com/btchip/comm/android/BTChipTransportAndroidHID.java +++ b/app/src/main/java/com/btchip/comm/android/BTChipTransportAndroidHID.java @@ -46,8 +46,12 @@ public class BTChipTransportAndroidHID implements BTChipTransport { HashMap deviceList = manager.getDeviceList(); for (UsbDevice device : deviceList.values()) { Timber.d("%04X:%04X %s, %s", device.getVendorId(), device.getProductId(), device.getManufacturerName(), device.getProductName()); - if ((device.getVendorId() == VID) && (device.getProductId() == PID_HID)) { - return device; + if (device.getVendorId() == VID) { + final int deviceProductId = device.getProductId(); + for (int pid : PID_HIDS) { + if (deviceProductId == pid) + return device; + } } } return null; @@ -74,7 +78,7 @@ public class BTChipTransportAndroidHID implements BTChipTransport { } private static final int VID = 0x2C97; - private static final int PID_HID = 0x0001; + private static final int[] PID_HIDS = {0x0001, 0x0004}; private UsbDeviceConnection connection; private UsbInterface dongleInterface; diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java index 5980fb5b..662776cd 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java @@ -1359,17 +1359,30 @@ public class LoginActivity extends BaseActivity if (Ledger.ENABLED) try { Ledger.connect(usbManager, usbDevice); - registerDetachReceiver(); - onLedgerAction(); - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(LoginActivity.this, - getString(R.string.toast_ledger_attached, usbDevice.getProductName()), - Toast.LENGTH_SHORT) - .show(); - } - }); + if (!Ledger.check()) { + Ledger.disconnect(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(LoginActivity.this, + getString(R.string.toast_ledger_start_app, usbDevice.getProductName()), + Toast.LENGTH_SHORT) + .show(); + } + }); + } else { + registerDetachReceiver(); + onLedgerAction(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(LoginActivity.this, + getString(R.string.toast_ledger_attached, usbDevice.getProductName()), + Toast.LENGTH_SHORT) + .show(); + } + }); + } } catch (IOException ex) { runOnUiThread(new Runnable() { @Override diff --git a/app/src/main/java/com/m2049r/xmrwallet/ledger/Instruction.java b/app/src/main/java/com/m2049r/xmrwallet/ledger/Instruction.java index 2e8e62d6..421aa7c3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/ledger/Instruction.java +++ b/app/src/main/java/com/m2049r/xmrwallet/ledger/Instruction.java @@ -134,6 +134,10 @@ public enum Instruction { return value; } + public byte getByteValue() { + return (byte) (value & 0xFF); + } + private int value; Instruction(int value) { diff --git a/app/src/main/java/com/m2049r/xmrwallet/ledger/Ledger.java b/app/src/main/java/com/m2049r/xmrwallet/ledger/Ledger.java index f73287cf..1d4a581d 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/ledger/Ledger.java +++ b/app/src/main/java/com/m2049r/xmrwallet/ledger/Ledger.java @@ -27,9 +27,11 @@ import com.btchip.BTChipException; import com.btchip.comm.BTChipTransport; import com.btchip.comm.android.BTChipTransportAndroidHID; import com.m2049r.xmrwallet.BuildConfig; +import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.util.Helper; import java.io.IOException; +import java.nio.charset.StandardCharsets; import timber.log.Timber; @@ -40,9 +42,11 @@ public class Ledger { static public final int LOOKAHEAD_SUBADDRESSES = 20; static public final String SUBADDRESS_LOOKAHEAD = LOOKAHEAD_ACCOUNTS + ":" + LOOKAHEAD_SUBADDRESSES; + private static final byte PROTOCOL_VERSION = 0x02; public static final int SW_OK = 0x9000; public static final int SW_INS_NOT_SUPPORTED = 0x6D00; public static final int OK[] = {SW_OK}; + public static final int MINIMUM_LEDGER_VERSION = (1 << 16) + (3 << 8) + (1); // 1.3.1 public static UsbDevice findDevice(UsbManager usbManager) { if (!ENABLED) return null; @@ -89,6 +93,21 @@ public class Ledger { } } + static public boolean check() { + if (Instance == null) return false; + byte[] moneroVersion = WalletManager.moneroVersion().getBytes(StandardCharsets.US_ASCII); + + try { + byte[] resp = Instance.exchangeApduNoOpt(Instruction.INS_RESET, moneroVersion, OK); + int deviceVersion = (resp[0] << 16) + (resp[1] << 8) + (resp[2]); + if (deviceVersion < MINIMUM_LEDGER_VERSION) + return false; + } catch (BTChipException ex) { // comm error - probably wrong app started on device + return false; + } + return true; + } + final private BTChipTransport transport; final private String name; private int lastSW = 0; @@ -112,7 +131,7 @@ public class Ledger { synchronized private byte[] exchangeRaw(byte[] apdu) { if (transport == null) throw new IllegalStateException("No transport (probably closed previously)"); - Timber.i("exchangeRaw %02x", apdu[1]); + Timber.d("exchangeRaw %02x", apdu[1]); Instruction ins = Instruction.fromByte(apdu[1]); if (listener != null) listener.onInstructionSend(ins, apdu); sniffOut(ins, apdu); @@ -120,7 +139,6 @@ public class Ledger { if (listener != null) listener.onInstructionReceive(ins, data); sniffIn(data); return data; - } private byte[] exchange(byte[] apdu) throws BTChipException { @@ -148,68 +166,19 @@ public class Ledger { throw new BTChipException("Invalid status", lastSW); } - private byte[] exchangeApdu(byte cla, byte ins, byte p1, byte p2, byte[] data, int acceptedSW[]) throws BTChipException { - byte[] apdu = new byte[data.length + 5]; - apdu[0] = cla; - apdu[1] = ins; - apdu[2] = p1; - apdu[3] = p2; - apdu[4] = (byte) (data.length); - System.arraycopy(data, 0, apdu, 5, data.length); + private byte[] exchangeApduNoOpt(Instruction instruction, byte[] data, int acceptedSW[]) + throws BTChipException { + byte[] apdu = new byte[data.length + 6]; + apdu[0] = PROTOCOL_VERSION; + apdu[1] = instruction.getByteValue(); + apdu[2] = 0; // p1 + apdu[3] = 0; // p2 + apdu[4] = (byte) (data.length + 1); // +1 because the opt byte is part of the data + apdu[5] = 0; // opt + System.arraycopy(data, 0, apdu, 6, data.length); return exchangeCheck(apdu, acceptedSW); } - private byte[] exchangeApdu(byte cla, byte ins, byte p1, byte p2, int length, int acceptedSW[]) throws BTChipException { - byte[] apdu = new byte[5]; - apdu[0] = cla; - apdu[1] = ins; - apdu[2] = p1; - apdu[3] = p2; - apdu[4] = (byte) (length); - return exchangeCheck(apdu, acceptedSW); - } - - private byte[] exchangeApduSplit(byte cla, byte ins, byte p1, byte p2, byte[] data, int acceptedSW[]) throws BTChipException { - int offset = 0; - byte[] result = null; - while (offset < data.length) { - int blockLength = ((data.length - offset) > 255 ? 255 : data.length - offset); - byte[] apdu = new byte[blockLength + 5]; - apdu[0] = cla; - apdu[1] = ins; - apdu[2] = p1; - apdu[3] = p2; - apdu[4] = (byte) (blockLength); - System.arraycopy(data, offset, apdu, 5, blockLength); - result = exchangeCheck(apdu, acceptedSW); - offset += blockLength; - } - return result; - } - - private byte[] exchangeApduSplit2(byte cla, byte ins, byte p1, byte p2, byte[] data, byte[] data2, int acceptedSW[]) throws BTChipException { - int offset = 0; - byte[] result = null; - int maxBlockSize = 255 - data2.length; - while (offset < data.length) { - int blockLength = ((data.length - offset) > maxBlockSize ? maxBlockSize : data.length - offset); - boolean lastBlock = ((offset + blockLength) == data.length); - byte[] apdu = new byte[blockLength + 5 + (lastBlock ? data2.length : 0)]; - apdu[0] = cla; - apdu[1] = ins; - apdu[2] = p1; - apdu[3] = p2; - apdu[4] = (byte) (blockLength + (lastBlock ? data2.length : 0)); - System.arraycopy(data, offset, apdu, 5, blockLength); - if (lastBlock) { - System.arraycopy(data2, 0, apdu, 5 + blockLength, data2.length); - } - result = exchangeCheck(apdu, acceptedSW); - offset += blockLength; - } - return result; - } - public interface Listener { void onInstructionSend(Instruction ins, byte[] apdu); @@ -251,7 +220,6 @@ public class Ledger { if (ins == Instruction.INS_GET_KEY) { snoopKey = (apdu[2] == 2); } - } private void sniffIn(byte[] data) { diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java index 692cd6f9..20033bce 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java @@ -354,4 +354,6 @@ public class WalletManager { static public native void logWarning(String category, String message); static public native void logError(String category, String message); + + static public native String moneroVersion(); } \ No newline at end of file diff --git a/app/src/main/res/values-cat/strings.xml b/app/src/main/res/values-cat/strings.xml index ce199fae..bbd42322 100644 --- a/app/src/main/res/values-cat/strings.xml +++ b/app/src/main/res/values-cat/strings.xml @@ -379,4 +379,6 @@ Contrasenya Ledger (avançat) Llavor de Ledger no vàlida! Introduir la vostra llavor del Ledger aquí té un elevat risc de seguretat! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f2332575..fb54bd3a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -382,4 +382,6 @@ Ledger-Passphrase (optional) Ungültiger Ledger-Seed! Deinen Ledger-Seed hier einzugeben, stellt ein erhebliches Sicherheitsrisiko dar! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 396e24ca..a567a2d4 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -381,4 +381,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index f7fd4249..2eca6999 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -381,4 +381,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 9856cce1..a33043d1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -371,4 +371,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 257910ef..87697955 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -379,4 +379,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b7d409cc..ddef175d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -385,4 +385,6 @@ Mot de passe Ledger (optionnel) Phrase mnémonique Ledger invalide ! Saisir votre phrase mnémonique Ledger ici est un risque majeur de sécurité ! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 50d78acd..83b6d90c 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -383,4 +383,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f3195d47..97737ff4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -384,4 +384,6 @@ Frase d\'accesso Ledger (opzionale) Seed di Ledger invalido! Inserire il tuo seed di Ledger qui è un grosso rischio! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 1ab0f264..b9558a06 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -427,4 +427,6 @@ Ledgerパスフレーズ (オプショナル) Ledgerのニーモニックシードは不正! ここにLedgerシードを入力するのは、大きなセキュリティリスクですよ! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index cd989bf3..51e7cbde 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -381,4 +381,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 060c5bda..4b9edced 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -381,4 +381,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index e2b6066f..74a9b974 100755 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -373,4 +373,6 @@ Senha da Ledger (opcional) Semente da Ledger inválida! Escrever a semente da sua Ledger aqui é um grande risco de segurança! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a4771161..3c96eddc 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -385,4 +385,6 @@ Palavra passe do Ledger (opcional) Semente do Ledger invalida! Introduzir a semente do Ledger aqui comporta um elevado risco de segurança! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index c96b0d5f..3f78b05f 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -381,4 +381,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5c9205ba..6d287b3f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -385,4 +385,6 @@ Пароль Ledger (необязательно) Ошибка фразы Ledger! Если вы пытаетесь ввести сюда фразу Ledger, это серьезная угроза для вашей безопасности! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 3c4a8d6d..895ce786 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -382,4 +382,6 @@ Ledger fráza (voliteľné) Neplatný Ledger Seed! Vloženie Ledger Seedu sem je vážne bezpečnostné riziko! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index ddda707c..317d21b1 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -382,4 +382,5 @@ Nevalidno seme iz knjige računa! Unošenje tvog semena iz knjige računa na ovom mestu ima veliki sigurnosni rizik! + Start Monero App on %1$s diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 6d0aadbc..53d1354f 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -366,4 +366,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-ua/strings.xml b/app/src/main/res/values-ua/strings.xml index 5a700eb4..a9dc3f47 100644 --- a/app/src/main/res/values-ua/strings.xml +++ b/app/src/main/res/values-ua/strings.xml @@ -385,4 +385,6 @@ Ledger Passphrase (optional) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + Start Monero App on %1$s diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 36f9adfc..863d6522 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -303,4 +303,6 @@ Ledger密码(高级模式) 无效的Ledger种子密语! 在此输入您的Ledger种子密语将会产生风险! + +Start Monero App on %1$s diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 88bde5d3..ed33cdcf 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -380,4 +380,6 @@ Ledger 密碼 (選填) 無效的 Ledger 種子碼! 在此輸入 Ledger 種子碼可能存在嚴重的安全風險! + + Start Monero App on %1$s diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6874e5aa..c6e9ae93 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -432,4 +432,6 @@ Entering your Ledger Seed here is a major security risk! %1$s (%2$s) + + Start Monero App on %1$s diff --git a/app/src/main/res/xml/usb_device_filter.xml b/app/src/main/res/xml/usb_device_filter.xml index 2fc6025f..ee5e64bb 100644 --- a/app/src/main/res/xml/usb_device_filter.xml +++ b/app/src/main/res/xml/usb_device_filter.xml @@ -6,4 +6,9 @@ product-id="1" vendor-id="11415" /> + + + \ No newline at end of file