From 43121607d0d75ff948654df49b5217eb937b4f0d Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Mon, 26 Oct 2020 11:53:08 +1100 Subject: [PATCH 1/3] Switch key pair generation mechanism --- build.gradle | 2 ++ .../loki/activities/RegisterActivity.kt | 27 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index bf872b1f1d..67c231b90b 100644 --- a/build.gradle +++ b/build.gradle @@ -145,6 +145,8 @@ dependencies { implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install implementation "org.whispersystems:curve25519-java:0.5.0" // Remote: + implementation "com.goterl.lazycode:lazysodium-java:4.3.0" + implementation "net.java.dev.jna:jna:5.6.0" implementation "com.google.protobuf:protobuf-java:2.5.0" implementation "com.fasterxml.jackson.core:jackson-databind:2.9.8" implementation "com.squareup.okhttp3:okhttp:3.12.1" diff --git a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt index 1ebf1ca1fd..a254a42dc1 100644 --- a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt @@ -15,6 +15,9 @@ import android.text.style.ClickableSpan import android.text.style.StyleSpan import android.view.View import android.widget.Toast +import com.goterl.lazycode.lazysodium.LazySodiumJava +import com.goterl.lazycode.lazysodium.SodiumJava +import com.goterl.lazycode.lazysodium.utils.KeyPair import kotlinx.android.synthetic.main.activity_register.* import network.loki.messenger.R import org.thoughtcrime.securesms.BaseActionBarActivity @@ -28,16 +31,15 @@ import org.thoughtcrime.securesms.util.Base64 import org.thoughtcrime.securesms.util.Hex import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.curve25519.Curve25519 -import org.whispersystems.libsignal.ecc.Curve -import org.whispersystems.libsignal.ecc.ECKeyPair +import org.whispersystems.libsignal.ecc.* import org.whispersystems.libsignal.util.KeyHelper import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey -import java.io.File -import java.io.FileOutputStream class RegisterActivity : BaseActionBarActivity() { + private val sodium = LazySodiumJava(SodiumJava()) private var seed: ByteArray? = null - private var keyPair: ECKeyPair? = null + private var ed25519KeyPair: KeyPair? = null + private var x25519KeyPair: ECKeyPair? = null set(value) { field = value; updatePublicKeyTextView() } // region Lifecycle @@ -72,7 +74,10 @@ class RegisterActivity : BaseActionBarActivity() { private fun updateKeyPair() { val seedCandidate = Curve25519.getInstance(Curve25519.BEST).generateSeed(16) try { - this.keyPair = Curve.generateKeyPair(seedCandidate + seedCandidate) // Validate the seed + val padding = ByteArray(16) { 0 } + ed25519KeyPair = sodium.cryptoSignSeedKeypair(seedCandidate + padding) + val x25519KeyPair = sodium.convertKeyPairEd25519ToCurve25519(ed25519KeyPair) + this.x25519KeyPair = ECKeyPair(DjbECPublicKey(x25519KeyPair.publicKey.asBytes), DjbECPrivateKey(x25519KeyPair.secretKey.asBytes)) } catch (exception: Exception) { return updateKeyPair() } @@ -80,7 +85,7 @@ class RegisterActivity : BaseActionBarActivity() { } private fun updatePublicKeyTextView() { - val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey + val hexEncodedPublicKey = x25519KeyPair!!.hexEncodedPublicKey val characterCount = hexEncodedPublicKey.count() var count = 0 val limit = 32 @@ -112,9 +117,9 @@ class RegisterActivity : BaseActionBarActivity() { // region Interaction private fun register() { IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed)) - 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())) - val userHexEncodedPublicKey = keyPair!!.hexEncodedPublicKey + 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())) + val userHexEncodedPublicKey = x25519KeyPair!!.hexEncodedPublicKey val registrationID = KeyHelper.generateRegistrationId(false) TextSecurePreferences.setLocalRegistrationId(this, registrationID) DatabaseFactory.getIdentityDatabase(this).saveIdentity(Address.fromSerialized(userHexEncodedPublicKey), @@ -129,7 +134,7 @@ class RegisterActivity : BaseActionBarActivity() { private fun copyPublicKey() { val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Session ID", keyPair!!.hexEncodedPublicKey) + val clip = ClipData.newPlainText("Session ID", x25519KeyPair!!.hexEncodedPublicKey) clipboard.setPrimaryClip(clip) Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() } From 4b2607a2d4d3a3018d039473fe623a6c05be90ce Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 29 Oct 2020 10:56:21 +1100 Subject: [PATCH 2/3] Switch to LazySodium for Android --- build.gradle | 11 +++++++++-- proguard-jna.pro | 3 +++ .../securesms/loki/activities/RegisterActivity.kt | 6 +++--- 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 proguard-jna.pro diff --git a/build.gradle b/build.gradle index f3fe570b03..9b21884457 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,12 @@ repositories { includeGroupByRegex "com\\.amulyakhare.*" } } + maven { + url "https://dl.bintray.com/terl/lazysodium-maven" + content { + includeGroupByRegex "com\\.goterl\\.lazycode.*" + } + } google() jcenter() maven { url "https://jitpack.io" } @@ -145,8 +151,8 @@ dependencies { implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install implementation "org.whispersystems:curve25519-java:0.5.0" // Remote: - implementation "com.goterl.lazycode:lazysodium-java:4.3.0" - implementation "net.java.dev.jna:jna:5.6.0" + implementation "com.goterl.lazycode:lazysodium-android:4.2.0@aar" + implementation "net.java.dev.jna:jna:5.5.0@aar" implementation "com.google.protobuf:protobuf-java:2.5.0" implementation "com.fasterxml.jackson.core:jackson-databind:2.9.8" implementation "com.squareup.okhttp3:okhttp:3.12.1" @@ -266,6 +272,7 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-dagger.pro', 'proguard-jackson.pro', + 'proguard-jna.pro', 'proguard-sqlite.pro', 'proguard-appcompat-v7.pro', 'proguard-square-okhttp.pro', diff --git a/proguard-jna.pro b/proguard-jna.pro new file mode 100644 index 0000000000..e80831221c --- /dev/null +++ b/proguard-jna.pro @@ -0,0 +1,3 @@ +-dontwarn java.awt.* +-keep class com.sun.jna.* { *; } +-keepclassmembers class * extends com.sun.jna.* { public *; } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt index a254a42dc1..eaf7e72408 100644 --- a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt @@ -15,8 +15,8 @@ import android.text.style.ClickableSpan import android.text.style.StyleSpan import android.view.View import android.widget.Toast -import com.goterl.lazycode.lazysodium.LazySodiumJava -import com.goterl.lazycode.lazysodium.SodiumJava +import com.goterl.lazycode.lazysodium.LazySodiumAndroid +import com.goterl.lazycode.lazysodium.SodiumAndroid import com.goterl.lazycode.lazysodium.utils.KeyPair import kotlinx.android.synthetic.main.activity_register.* import network.loki.messenger.R @@ -36,7 +36,7 @@ import org.whispersystems.libsignal.util.KeyHelper import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey class RegisterActivity : BaseActionBarActivity() { - private val sodium = LazySodiumJava(SodiumJava()) + private val sodium = LazySodiumAndroid(SodiumAndroid()) private var seed: ByteArray? = null private var ed25519KeyPair: KeyPair? = null private var x25519KeyPair: ECKeyPair? = null From 1dbee27c9a6f7e4a3bba9010a3c62aeb724a2d8b Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 29 Oct 2020 11:06:02 +1100 Subject: [PATCH 3/3] Store ED25519 key pair for future use --- src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java | 2 ++ .../thoughtcrime/securesms/loki/activities/RegisterActivity.kt | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java index f2fc74b687..b8b5dd6518 100644 --- a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java +++ b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java @@ -51,6 +51,8 @@ public class IdentityKeyUtil { public static final String IDENTITY_PUBLIC_KEY_PREF = "pref_identity_public_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_SECRET_KEY = "pref_ed25519_secret_key"; public static final String lokiSeedKey = "loki_seed"; diff --git a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt index eaf7e72408..1737b01e5d 100644 --- a/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/activities/RegisterActivity.kt @@ -13,6 +13,7 @@ import android.text.SpannableStringBuilder import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.text.style.StyleSpan +import android.util.Log import android.view.View import android.widget.Toast import com.goterl.lazycode.lazysodium.LazySodiumAndroid @@ -119,6 +120,8 @@ class RegisterActivity : BaseActionBarActivity() { IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed)) 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 registrationID = KeyHelper.generateRegistrationId(false) TextSecurePreferences.setLocalRegistrationId(this, registrationID)