mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 17:58:25 +00:00
Fix restoration from seed issue
This commit is contained in:
parent
eddd6dc0e6
commit
9102215ca0
@ -336,7 +336,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
|||||||
case PREFERENCE_CATEGORY_LINKED_DEVICES: break;
|
case PREFERENCE_CATEGORY_LINKED_DEVICES: break;
|
||||||
case PREFERENCE_CATEGORY_SEED:
|
case PREFERENCE_CATEGORY_SEED:
|
||||||
try {
|
try {
|
||||||
String hexEncodedSeed = IdentityKeyUtil.retrieve(getContext(), IdentityKeyUtil.lokiSeedKey);
|
String hexEncodedSeed = IdentityKeyUtil.retrieve(getContext(), IdentityKeyUtil.LOKI_SEED);
|
||||||
if (hexEncodedSeed == null) {
|
if (hexEncodedSeed == null) {
|
||||||
hexEncodedSeed = HexEncodingKt.getHexEncodedPrivateKey(IdentityKeyUtil.getIdentityKeyPair(getContext())); // Legacy account
|
hexEncodedSeed = HexEncodingKt.getHexEncodedPrivateKey(IdentityKeyUtil.getIdentityKeyPair(getContext())); // Legacy account
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,7 @@ public class IdentityKeyUtil {
|
|||||||
public static final String IDENTITY_PRIVATE_KEY_PREF = "pref_identity_private_v3";
|
public static final String IDENTITY_PRIVATE_KEY_PREF = "pref_identity_private_v3";
|
||||||
public static final String ED25519_PUBLIC_KEY = "pref_ed25519_public_key";
|
public static final String ED25519_PUBLIC_KEY = "pref_ed25519_public_key";
|
||||||
public static final String ED25519_SECRET_KEY = "pref_ed25519_secret_key";
|
public static final String ED25519_SECRET_KEY = "pref_ed25519_secret_key";
|
||||||
|
public static final String LOKI_SEED = "loki_seed";
|
||||||
public static final String lokiSeedKey = "loki_seed";
|
|
||||||
|
|
||||||
public static boolean hasIdentityKey(Context context) {
|
public static boolean hasIdentityKey(Context context) {
|
||||||
SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
|
SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
|
||||||
|
@ -85,7 +85,7 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega
|
|||||||
seed = seedCandidate
|
seed = seedCandidate
|
||||||
}
|
}
|
||||||
generateKeyPair()
|
generateKeyPair()
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed))
|
IdentityKeyUtil.save(this, IdentityKeyUtil.LOKI_SEED, Hex.toStringCondensed(seed))
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(keyPair!!.publicKey.serialize()))
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(keyPair!!.publicKey.serialize()))
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair!!.privateKey.serialize()))
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair!!.privateKey.serialize()))
|
||||||
val userHexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
|
val userHexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
|
||||||
@ -140,7 +140,7 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun reset() {
|
private fun reset() {
|
||||||
IdentityKeyUtil.delete(this, IdentityKeyUtil.lokiSeedKey)
|
IdentityKeyUtil.delete(this, IdentityKeyUtil.LOKI_SEED)
|
||||||
TextSecurePreferences.removeLocalNumber(this)
|
TextSecurePreferences.removeLocalNumber(this)
|
||||||
TextSecurePreferences.setHasSeenWelcomeScreen(this, false)
|
TextSecurePreferences.setHasSeenWelcomeScreen(this, false)
|
||||||
TextSecurePreferences.setPromptedPushRegistration(this, false)
|
TextSecurePreferences.setPromptedPushRegistration(this, false)
|
||||||
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
|||||||
import org.thoughtcrime.securesms.database.Address
|
import org.thoughtcrime.securesms.database.Address
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase
|
import org.thoughtcrime.securesms.database.IdentityDatabase
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.KeyPairUtilities
|
||||||
import org.thoughtcrime.securesms.loki.utilities.push
|
import org.thoughtcrime.securesms.loki.utilities.push
|
||||||
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
||||||
import org.thoughtcrime.securesms.util.Base64
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
@ -37,7 +38,6 @@ import org.whispersystems.libsignal.util.KeyHelper
|
|||||||
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
||||||
|
|
||||||
class RegisterActivity : BaseActionBarActivity() {
|
class RegisterActivity : BaseActionBarActivity() {
|
||||||
private val sodium = LazySodiumAndroid(SodiumAndroid())
|
|
||||||
private var seed: ByteArray? = null
|
private var seed: ByteArray? = null
|
||||||
private var ed25519KeyPair: KeyPair? = null
|
private var ed25519KeyPair: KeyPair? = null
|
||||||
private var x25519KeyPair: ECKeyPair? = null
|
private var x25519KeyPair: ECKeyPair? = null
|
||||||
@ -73,16 +73,10 @@ class RegisterActivity : BaseActionBarActivity() {
|
|||||||
|
|
||||||
// region Updating
|
// region Updating
|
||||||
private fun updateKeyPair() {
|
private fun updateKeyPair() {
|
||||||
val seedCandidate = Curve25519.getInstance(Curve25519.BEST).generateSeed(16)
|
val keyPairGenerationResult = KeyPairUtilities.generate()
|
||||||
try {
|
seed = keyPairGenerationResult.seed
|
||||||
val padding = ByteArray(16) { 0 }
|
ed25519KeyPair = keyPairGenerationResult.ed25519KeyPair
|
||||||
ed25519KeyPair = sodium.cryptoSignSeedKeypair(seedCandidate + padding)
|
x25519KeyPair = keyPairGenerationResult.x25519KeyPair
|
||||||
val x25519KeyPair = sodium.convertKeyPairEd25519ToCurve25519(ed25519KeyPair)
|
|
||||||
this.x25519KeyPair = ECKeyPair(DjbECPublicKey(x25519KeyPair.publicKey.asBytes), DjbECPrivateKey(x25519KeyPair.secretKey.asBytes))
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
return updateKeyPair()
|
|
||||||
}
|
|
||||||
seed = seedCandidate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePublicKeyTextView() {
|
private fun updatePublicKeyTextView() {
|
||||||
@ -117,11 +111,7 @@ class RegisterActivity : BaseActionBarActivity() {
|
|||||||
|
|
||||||
// region Interaction
|
// region Interaction
|
||||||
private fun register() {
|
private fun register() {
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed))
|
KeyPairUtilities.store(this, seed!!, ed25519KeyPair!!, x25519KeyPair!!)
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(x25519KeyPair!!.publicKey.serialize()))
|
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(x25519KeyPair!!.privateKey.serialize()))
|
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.ED25519_PUBLIC_KEY, Base64.encodeBytes(ed25519KeyPair!!.publicKey.asBytes))
|
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.ED25519_SECRET_KEY, Base64.encodeBytes(ed25519KeyPair!!.secretKey.asBytes))
|
|
||||||
val userHexEncodedPublicKey = x25519KeyPair!!.hexEncodedPublicKey
|
val userHexEncodedPublicKey = x25519KeyPair!!.hexEncodedPublicKey
|
||||||
val registrationID = KeyHelper.generateRegistrationId(false)
|
val registrationID = KeyHelper.generateRegistrationId(false)
|
||||||
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
||||||
|
@ -18,18 +18,15 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
|||||||
import org.thoughtcrime.securesms.database.Address
|
import org.thoughtcrime.securesms.database.Address
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase
|
import org.thoughtcrime.securesms.database.IdentityDatabase
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.KeyPairUtilities
|
||||||
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
||||||
import org.thoughtcrime.securesms.loki.utilities.push
|
import org.thoughtcrime.securesms.loki.utilities.push
|
||||||
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
||||||
import org.thoughtcrime.securesms.util.Base64
|
|
||||||
import org.thoughtcrime.securesms.util.Hex
|
import org.thoughtcrime.securesms.util.Hex
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.libsignal.ecc.Curve
|
|
||||||
import org.whispersystems.libsignal.util.KeyHelper
|
import org.whispersystems.libsignal.util.KeyHelper
|
||||||
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
||||||
import java.io.File
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
|
|
||||||
class RestoreActivity : BaseActionBarActivity() {
|
class RestoreActivity : BaseActionBarActivity() {
|
||||||
|
|
||||||
@ -68,13 +65,11 @@ class RestoreActivity : BaseActionBarActivity() {
|
|||||||
MnemonicUtilities.loadFileContents(this, fileName)
|
MnemonicUtilities.loadFileContents(this, fileName)
|
||||||
}
|
}
|
||||||
val hexEncodedSeed = MnemonicCodec(loadFileContents).decode(mnemonic)
|
val hexEncodedSeed = MnemonicCodec(loadFileContents).decode(mnemonic)
|
||||||
var seed = Hex.fromStringCondensed(hexEncodedSeed)
|
val seed = Hex.fromStringCondensed(hexEncodedSeed)
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed))
|
val keyPairGenerationResult = KeyPairUtilities.generate(seed)
|
||||||
if (seed.size == 16) { seed = seed + seed }
|
val x25519KeyPair = keyPairGenerationResult.x25519KeyPair
|
||||||
val keyPair = Curve.generateKeyPair(seed)
|
KeyPairUtilities.store(this, seed, keyPairGenerationResult.ed25519KeyPair, x25519KeyPair)
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(keyPair.publicKey.serialize()))
|
val userHexEncodedPublicKey = x25519KeyPair.hexEncodedPublicKey
|
||||||
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair.privateKey.serialize()))
|
|
||||||
val userHexEncodedPublicKey = keyPair.hexEncodedPublicKey
|
|
||||||
val registrationID = KeyHelper.generateRegistrationId(false)
|
val registrationID = KeyHelper.generateRegistrationId(false)
|
||||||
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
||||||
DatabaseFactory.getIdentityDatabase(this).saveIdentity(Address.fromSerialized(userHexEncodedPublicKey),
|
DatabaseFactory.getIdentityDatabase(this).saveIdentity(Address.fromSerialized(userHexEncodedPublicKey),
|
||||||
|
@ -7,7 +7,6 @@ import android.os.Bundle
|
|||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.util.Log
|
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_seed.*
|
import kotlinx.android.synthetic.main.activity_seed.*
|
||||||
@ -19,12 +18,11 @@ import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
|||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class SeedActivity : BaseActionBarActivity() {
|
class SeedActivity : BaseActionBarActivity() {
|
||||||
|
|
||||||
private val seed by lazy {
|
private val seed by lazy {
|
||||||
var hexEncodedSeed = IdentityKeyUtil.retrieve(this, IdentityKeyUtil.lokiSeedKey)
|
var hexEncodedSeed = IdentityKeyUtil.retrieve(this, IdentityKeyUtil.LOKI_SEED)
|
||||||
if (hexEncodedSeed == null) {
|
if (hexEncodedSeed == null) {
|
||||||
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(this).hexEncodedPrivateKey // Legacy account
|
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(this).hexEncodedPrivateKey // Legacy account
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import android.graphics.Color
|
|||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.WindowManager
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
@ -23,7 +22,7 @@ import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
|||||||
class SeedDialog : DialogFragment() {
|
class SeedDialog : DialogFragment() {
|
||||||
|
|
||||||
private val seed by lazy {
|
private val seed by lazy {
|
||||||
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.lokiSeedKey)
|
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
|
||||||
if (hexEncodedSeed == null) {
|
if (hexEncodedSeed == null) {
|
||||||
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
|
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.utilities
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.goterl.lazycode.lazysodium.LazySodiumAndroid
|
||||||
|
import com.goterl.lazycode.lazysodium.SodiumAndroid
|
||||||
|
import com.goterl.lazycode.lazysodium.utils.KeyPair
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
|
import org.thoughtcrime.securesms.util.Hex
|
||||||
|
import org.whispersystems.curve25519.Curve25519
|
||||||
|
import org.whispersystems.libsignal.ecc.DjbECPrivateKey
|
||||||
|
import org.whispersystems.libsignal.ecc.DjbECPublicKey
|
||||||
|
import org.whispersystems.libsignal.ecc.ECKeyPair
|
||||||
|
|
||||||
|
object KeyPairUtilities {
|
||||||
|
|
||||||
|
data class KeyPairGenerationResult(
|
||||||
|
val seed: ByteArray,
|
||||||
|
val ed25519KeyPair: KeyPair,
|
||||||
|
val x25519KeyPair: ECKeyPair
|
||||||
|
)
|
||||||
|
|
||||||
|
fun generate(): KeyPairGenerationResult {
|
||||||
|
val seed = Curve25519.getInstance(Curve25519.BEST).generateSeed(16)
|
||||||
|
try {
|
||||||
|
return generate(seed)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
return generate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generate(seed: ByteArray): KeyPairGenerationResult {
|
||||||
|
val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||||
|
val padding = ByteArray(16) { 0 }
|
||||||
|
val ed25519KeyPair = sodium.cryptoSignSeedKeypair(seed + padding)
|
||||||
|
val sodiumX25519KeyPair = sodium.convertKeyPairEd25519ToCurve25519(ed25519KeyPair)
|
||||||
|
val x25519KeyPair = ECKeyPair(DjbECPublicKey(sodiumX25519KeyPair.publicKey.asBytes), DjbECPrivateKey(sodiumX25519KeyPair.secretKey.asBytes))
|
||||||
|
return KeyPairGenerationResult(seed, ed25519KeyPair, x25519KeyPair)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun store(context: Context, seed: ByteArray, ed25519KeyPair: KeyPair, x25519KeyPair: ECKeyPair) {
|
||||||
|
IdentityKeyUtil.save(context, IdentityKeyUtil.LOKI_SEED, Hex.toStringCondensed(seed))
|
||||||
|
IdentityKeyUtil.save(context, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(x25519KeyPair.publicKey.serialize()))
|
||||||
|
IdentityKeyUtil.save(context, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(x25519KeyPair.privateKey.serialize()))
|
||||||
|
IdentityKeyUtil.save(context, IdentityKeyUtil.ED25519_PUBLIC_KEY, Base64.encodeBytes(ed25519KeyPair.publicKey.asBytes))
|
||||||
|
IdentityKeyUtil.save(context, IdentityKeyUtil.ED25519_SECRET_KEY, Base64.encodeBytes(ed25519KeyPair.secretKey.asBytes))
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user