diff --git a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeHelper.kt b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeHelper.kt index e6ebd80b..644de0cf 100644 --- a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeHelper.kt +++ b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeHelper.kt @@ -1,6 +1,7 @@ package com.tonapps.wallet.data.passcode import android.content.Context +import android.util.Log import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tonapps.extensions.logError import com.tonapps.wallet.data.account.AccountRepository @@ -35,11 +36,12 @@ class PasscodeHelper( } suspend fun isValid(context: Context, code: String): Boolean { - return if (store.hasPinCode && store.compare(code)) { + return store.hasPinCode && store.compare(code) + /*return if (store.hasPinCode && store.compare(code)) { true } else { isValidLegacy(context, code) - } + }*/ } private suspend fun isValidLegacy(context: Context, code: String): Boolean = withContext(Dispatchers.IO) { diff --git a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeManager.kt b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeManager.kt index 24408937..453a5b10 100644 --- a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeManager.kt +++ b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/PasscodeManager.kt @@ -155,16 +155,15 @@ class PasscodeManager( return@withContext confirmationMigration(context) } - val showDialog = if (settingsRepository.biometric && PasscodeBiometric.isAvailableOnDevice(context)) { - !PasscodeBiometric.showPrompt(context, title) - } else { + if (settingsRepository.biometric && PasscodeBiometric.isAvailableOnDevice(context) && PasscodeBiometric.showPrompt(context, title)) { true - } - - if (showDialog) { - PasscodeDialog.confirmation(context) } else { - true + val passcode = PasscodeDialog.request(context) + if (passcode.isNullOrBlank()) { + false + } else { + helper.isValid(context, passcode) + } } } diff --git a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/source/PasscodeStore.kt b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/source/PasscodeStore.kt index aa9109fe..610dee74 100644 --- a/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/source/PasscodeStore.kt +++ b/apps/wallet/data/passcode/src/main/java/com/tonapps/wallet/data/passcode/source/PasscodeStore.kt @@ -2,6 +2,7 @@ package com.tonapps.wallet.data.passcode.source import android.content.Context import android.content.SharedPreferences +import android.util.Log import com.tonapps.extensions.clear import com.tonapps.extensions.putString import com.tonapps.extensions.remove diff --git a/apps/wallet/data/rn/build.gradle.kts b/apps/wallet/data/rn/build.gradle.kts index d50032f8..fe41b76d 100644 --- a/apps/wallet/data/rn/build.gradle.kts +++ b/apps/wallet/data/rn/build.gradle.kts @@ -12,6 +12,8 @@ dependencies { api(Dependence.Firebase.crashlytics) implementation(Dependence.AndroidX.biometric) + implementation(Dependence.TON.crypto) + implementation(project(Dependence.Lib.sqlite)) implementation(project(Dependence.Lib.security)) implementation(project(Dependence.Lib.extensions)) diff --git a/apps/wallet/data/rn/src/main/java/com/tonapps/wallet/data/rn/ScryptBox.kt b/apps/wallet/data/rn/src/main/java/com/tonapps/wallet/data/rn/ScryptBox.kt index c266103e..597db20b 100644 --- a/apps/wallet/data/rn/src/main/java/com/tonapps/wallet/data/rn/ScryptBox.kt +++ b/apps/wallet/data/rn/src/main/java/com/tonapps/wallet/data/rn/ScryptBox.kt @@ -40,12 +40,32 @@ internal object ScryptBox { if (state.kind != "encrypted-scrypt-tweetnacl") { throw Exception("Invalid state kind") } + val bytes = decrypt1(passcode, state) ?: decrypt2(passcode, state) ?: throw Exception("cryptoSecretboxOpen failed") + return bytes.decodeToString() + } + + private fun decrypt1(passcode: String, state: SeedState): ByteArray? { val salt = state.salt.hex() val passcodeHash = passcodeHash(passcode, salt) val nonce = salt.copyOfRange(0, 24) val clearText = state.ciphertext.hex() - val pt = Sodium.cryptoSecretboxOpen(clearText, nonce, passcodeHash) ?: throw Exception("cryptoSecretboxOpen failed") - return pt.decodeToString() + return cryptoSecretBoxOpen(clearText, nonce, passcodeHash) + } + + private fun decrypt2(passcode: String, state: SeedState): ByteArray? { + val salt = org.ton.crypto.hex(state.salt) + val passcodeHash = passcodeHash(passcode, salt) + val nonce = salt.copyOfRange(0, 24) + val clearText = org.ton.crypto.hex(state.ciphertext) + return cryptoSecretBoxOpen(clearText, nonce, passcodeHash) + } + + private fun cryptoSecretBoxOpen( + box: ByteArray, + nonce: ByteArray, + key: ByteArray + ): ByteArray? { + return Sodium.cryptoSecretboxOpen(box, nonce, key) } } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/AccountRepository.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/AccountRepository.kt index d3da32f0..7c2a1f2d 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/AccountRepository.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/AccountRepository.kt @@ -1,5 +1,6 @@ package com.tonapps.tonkeeper.extensions +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tonapps.wallet.data.account.AccountRepository import com.tonapps.wallet.data.rn.RNException import com.tonapps.wallet.data.rn.RNLegacy @@ -13,15 +14,20 @@ suspend fun AccountRepository.requestPrivateKey( activity: NavigationActivity, rnLegacy: RNLegacy, walletId: String, -): PrivateKeyEd25519 = withContext(Dispatchers.IO) { - val privateKeyEd25519 = getPrivateKey(walletId) - if (privateKeyEd25519 != null) { - privateKeyEd25519 - } else { - val vaultState = rnLegacy.requestVault(activity) - val mnemonic = vaultState.getDecryptedData(walletId)?.mnemonic ?: throw RNException.NotFoundMnemonic(walletId) - val seed = Mnemonic.toSeed(splitMnemonic(mnemonic)) - PrivateKeyEd25519(seed) +): PrivateKeyEd25519? = withContext(Dispatchers.IO) { + try { + val privateKeyEd25519 = getPrivateKey(walletId) + if (privateKeyEd25519 != null) { + privateKeyEd25519 + } else { + val vaultState = rnLegacy.requestVault(activity) + val mnemonic = vaultState.getDecryptedData(walletId)?.mnemonic ?: throw RNException.NotFoundMnemonic(walletId) + val seed = Mnemonic.toSeed(splitMnemonic(mnemonic)) + PrivateKeyEd25519(seed) + } + } catch (e: Throwable) { + FirebaseCrashlytics.getInstance().recordException(e) + null } } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignProof.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignProof.kt index 134ff75c..0ebed55d 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignProof.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignProof.kt @@ -8,6 +8,7 @@ import com.tonapps.blockchain.ton.proof.TONProof.Request import com.tonapps.tonkeeper.extensions.requestPrivateKey import com.tonapps.tonkeeper.ui.screen.external.qr.keystone.sign.KeystoneSignScreen import com.tonapps.tonkeeper.ui.screen.ledger.proof.LedgerProofScreen +import com.tonapps.tonkeeper.ui.screen.send.main.SendException import com.tonapps.wallet.data.account.AccountRepository import com.tonapps.wallet.data.account.entities.WalletEntity import com.tonapps.wallet.data.passcode.PasscodeManager @@ -95,7 +96,7 @@ class SignProof( throw CancellationException("Passcode cancelled") } - val privateKey = accountRepository.requestPrivateKey(activity, rnLegacy, wallet.id) + val privateKey = accountRepository.requestPrivateKey(activity, rnLegacy, wallet.id) ?: throw SendException.UnableSendTransaction() return TONProof.sign( address = wallet.contract.address, diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignTransaction.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignTransaction.kt index e13e0205..af7c51e4 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignTransaction.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/usecase/sign/SignTransaction.kt @@ -5,6 +5,7 @@ import com.tonapps.blockchain.ton.extensions.EmptyPrivateKeyEd25519.sign import com.tonapps.blockchain.ton.extensions.hex import com.tonapps.ledger.ton.Transaction import com.tonapps.tonkeeper.core.signer.SignerHelper +import com.tonapps.tonkeeper.extensions.requestPrivateKey import com.tonapps.tonkeeper.ui.screen.external.qr.keystone.sign.KeystoneSignScreen import com.tonapps.tonkeeper.ui.screen.external.qr.signer.sign.SignerSignScreen import com.tonapps.tonkeeper.ui.screen.ledger.sign.LedgerSignScreen @@ -114,7 +115,7 @@ class SignTransaction( if (!isValidPasscode) { throw SendException.WrongPasscode() } - val privateKey = accountRepository.getPrivateKey(wallet.id) ?: throw SendException.UnableSendTransaction() + val privateKey = accountRepository.requestPrivateKey(activity, rnLegacy, wallet.id) ?: throw SendException.UnableSendTransaction() val hash = privateKey.sign(unsignedBody.hash()) BitString(hash) } diff --git a/apps/wallet/instance/main/build.gradle.kts b/apps/wallet/instance/main/build.gradle.kts index b2bc3001..95726d2f 100644 --- a/apps/wallet/instance/main/build.gradle.kts +++ b/apps/wallet/instance/main/build.gradle.kts @@ -24,7 +24,7 @@ android { targetSdk = 34 versionCode = 600 - versionName = "5.0.12" // Format is "major.minor.patch" (e.g. "1.0.0") and only numbers are allowed + versionName = "5.0.14" // Format is "major.minor.patch" (e.g. "1.0.0") and only numbers are allowed testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/ui/uikit/core/src/main/java/uikit/widget/webview/WebViewFixed.kt b/ui/uikit/core/src/main/java/uikit/widget/webview/WebViewFixed.kt index 1495caaa..7395214d 100644 --- a/ui/uikit/core/src/main/java/uikit/widget/webview/WebViewFixed.kt +++ b/ui/uikit/core/src/main/java/uikit/widget/webview/WebViewFixed.kt @@ -135,7 +135,7 @@ open class WebViewFixed @JvmOverloads constructor( request.deny() } - override fun onCreateWindow( + /*override fun onCreateWindow( view: WebView?, isDialog: Boolean, isUserGesture: Boolean, @@ -152,7 +152,7 @@ open class WebViewFixed @JvmOverloads constructor( // Deny file chooser filePathCallback.onReceiveValue(null) return true - } + }*/ } applyAndroidWebViewBridge()