Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passphrase spaces #86

Merged
merged 3 commits into from
Nov 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@

@RunWith(AndroidJUnit4.class)
public class AccountUtilsTest {
private String mnemonic;
private String mnemonic12;
private String mnemonic24;
private Context context;
private String pin = "1234";
private String passPhrase = "this_is_a_passphrase";

@Before
public void before(){
String[] mnemonicWords = {
String[] mnemonicWords12 = {
"abandon",
"ability",
"able",
Expand All @@ -46,13 +47,41 @@ public void before(){
"accident"
};

mnemonic = TextUtils.join(" ", mnemonicWords);
String[] mnemonicWords24 = {
"abandon",
"ability",
"able",
"about",
"above",
"absent",
"absorb",
"abstract",
"absurd",
"abuse",
"access",
"accident",
"account",
"accuse",
"achieve",
"acid",
"acoustic",
"acquire",
"across",
"act",
"action",
"actor",
"actress",
"actual"
};

mnemonic12 = TextUtils.join(" ", mnemonicWords12);
mnemonic24 = TextUtils.join(" ", mnemonicWords24);
context = InstrumentationRegistry.getTargetContext();
}

@Test
public void basic_encryption_mnemonic() {
AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic, null, pin);
AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic12, null, pin);
String phrase = WalletApplication.localStore.getEncryptedPhrase();

assertNotNull(phrase);
Expand All @@ -62,13 +91,12 @@ public void basic_encryption_mnemonic() {

Pair<String, String> decryptedPair = AccountUtils.Companion.getOldDecryptedPair(phrase, keyPair.getPrivate());
assertNull(decryptedPair.component2());
assertEquals(decryptedPair.component1(), mnemonic);
assertEquals(decryptedPair.component1(), mnemonic12);
}

@Test
public void basic_encryption_mnemonic_with_passphrase() {

AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic, passPhrase, pin);
AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic12, passPhrase, pin);
String phrase = WalletApplication.localStore.getEncryptedPhrase();
assertNotNull(phrase);

Expand All @@ -78,28 +106,46 @@ public void basic_encryption_mnemonic_with_passphrase() {
String decryptedPhrase = AccountUtils.Companion.getDecryptedString(phrase, keyPair);
String decryptedPassphrase = AccountUtils.Companion.getDecryptedPassphrase(WalletApplication.localStore.getEncryptedPassphrase(), keyPair);

assertEquals(mnemonic, decryptedPhrase);
assertEquals(mnemonic12, decryptedPhrase);
assertEquals(passPhrase, decryptedPassphrase);
}


//TODO: https://github.com/Block-Equity/stellar-android-wallet/issues/74
// @Test
// public void basic_encryption_mnemonic_with_pass_phrase_with_spaces() {
// Context context = InstrumentationRegistry.getTargetContext();
// String mnemonicString = String.join(" ", mnemonic);
// String passPhrase = "this is a passphrase";
//
// String phrase = AccountUtils.Companion.encryptAndStoreWallet(InstrumentationRegistry.getTargetContext(), mnemonicString, passPhrase, pin);
// assertNotNull(phrase);
//
// KeyPair keyPair = AccountUtils.Companion.getPinMasterKey(context, pin);
// assertNotNull(keyPair);
//
// Pair<String, String> decryptedPair = AccountUtils.Companion.getOldDecryptedPair(phrase, keyPair.getPrivate());
// assertEquals(passPhrase, decryptedPair.component2());
// assertEquals(decryptedPair.component1(), mnemonicString);
// }
@Test
public void basic_encryption_mnemonic12_with_pass_phrase_with_spaces() {
String passphrase = "passphrase with spaces";

AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic12, passphrase, pin);
String phrase = WalletApplication.localStore.getEncryptedPhrase();
assertNotNull(phrase);

KeyPair keyPair = AccountUtils.Companion.getPinMasterKey(context, pin);
assertNotNull(keyPair);

String decryptedPhrase = AccountUtils.Companion.getDecryptedString(phrase, keyPair);
String decryptedPassphrase = AccountUtils.Companion.getDecryptedPassphrase(WalletApplication.localStore.getEncryptedPassphrase(), keyPair);

assertEquals(mnemonic12, decryptedPhrase);
assertEquals(passphrase, decryptedPassphrase);
}

@Test
public void basic_encryption_mnemonic24_with_pass_phrase_with_spaces() {
String passphrase = "passphrase with spaces";

AccountUtils.Companion.encryptAndStoreWallet(context, mnemonic24, passphrase, pin);
String phrase = WalletApplication.localStore.getEncryptedPhrase();
assertNotNull(phrase);

KeyPair keyPair = AccountUtils.Companion.getPinMasterKey(context, pin);
assertNotNull(keyPair);

String decryptedPhrase = AccountUtils.Companion.getDecryptedString(phrase, keyPair);
String decryptedPassphrase = AccountUtils.Companion.getDecryptedPassphrase(WalletApplication.localStore.getEncryptedPassphrase(), keyPair);

assertEquals(mnemonic24, decryptedPhrase);
assertEquals(passphrase, decryptedPassphrase);
}

// TODO: Remove in new app
// Creates a passphrase wallet with the <= 1.0.3 version
Expand All @@ -116,7 +162,7 @@ public void backwards_compatibility_test_login() {
CipherWrapper cipherWrapper = new CipherWrapper("RSA/ECB/PKCS1Padding");

assert masterKey != null;
String encryptedPhrase = cipherWrapper.encrypt(mnemonic + " " + passPhrase, masterKey.getPublic(), false);
String encryptedPhrase = cipherWrapper.encrypt(mnemonic12 + " " + passPhrase, masterKey.getPublic(), false);
Copy link
Collaborator

@dabitdev dabitdev Nov 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not he old way of encrypting mnemoni + passphrase?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should u write a new test for the passphrase encryption only?
cipherWrapper.encrypt(passPhrase)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this entire problem only exists in the old wallet lol, cause we are using a space separating the mnemonic and passphrase :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what line is that cipherWrapper.encrypt(passPhrase)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never-mind, I got confused


WalletApplication.localStore.setEncryptedPhrase(encryptedPhrase);
WalletApplication.localStore.setPassphraseUsed(true);
Expand All @@ -139,7 +185,7 @@ public void backwards_compatibility_test_login() {
decryptedPassphrase = decryptedPair.getSecond();
}

assertEquals(mnemonic, decryptedPhrase);
assertEquals(mnemonic12, decryptedPhrase);
assertEquals(passPhrase, decryptedPassphrase);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import blockeq.com.stellarwallet.activities.PinActivity.Companion.PIN_REQUEST_CO
import blockeq.com.stellarwallet.helpers.Constants
import blockeq.com.stellarwallet.helpers.PassphraseDialogHelper
import blockeq.com.stellarwallet.models.PinType
import blockeq.com.stellarwallet.utils.StringFormat
import kotlinx.android.synthetic.main.activity_recover_wallet.*


Expand Down Expand Up @@ -60,7 +61,7 @@ class RecoverWalletActivity : BaseActivity() {

nextButton.setOnClickListener {
val recoveryString = getMnemonicString()
val wordCount = getWordCount(recoveryString)
val wordCount = StringFormat.getWordCount(recoveryString)

WalletApplication.localStore.isRecoveryPhrase = isRecoveryPhrase

Expand Down Expand Up @@ -116,10 +117,6 @@ class RecoverWalletActivity : BaseActivity() {
//endregion

//region Helper functions
private fun getWordCount(word : String) : Int {
return word.split(" ".toRegex()).size
}

private fun getMnemonicString() : String {
return if (isRecoveryPhrase) {
phraseEditText.text.toString().trim()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class ShowMnemonicActivity : BaseActivity(), View.OnClickListener {
}

mnemonicString = String(mnemonic)
return String(mnemonic).split(" ".toRegex()).dropLastWhile { it.isEmpty() } as ArrayList
return mnemonicString!!.split(" ".toRegex()).dropLastWhile { it.isEmpty() } as ArrayList
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you put !!? it looks like mnemonicString can not be null since is assigned to a new String object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kotlin's compiler apparently is not perfect and they don't allow it :(

}
}

Expand Down
28 changes: 23 additions & 5 deletions app/src/main/java/blockeq/com/stellarwallet/utils/AccountUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,33 @@ class AccountUtils {
fun getOldDecryptedPair(encryptedPhrase: String, privateKey: PrivateKey) : Pair<String, String?> {
val cipherWrapper = CipherWrapper(CIPHER_TRANSFORMATION)
var passphrase : String? = null
val decryptedData = if (WalletApplication.localStore.isPassphraseUsed) {
val decryptedPhrase: String

if (WalletApplication.localStore.isPassphraseUsed) {
val decryptedString = cipherWrapper.decrypt(encryptedPhrase, privateKey)
passphrase = decryptedString.substring(decryptedString.lastIndexOf(" ") + 1)
decryptedString.substring(0, decryptedString.lastIndexOf(" "))

val wordCount = StringFormat.getWordCount(decryptedString)
val words = decryptedString.split(" ".toRegex()).dropLastWhile { it.isEmpty() } as ArrayList

val range = if (wordCount <= 24) {
0..11
} else {
0..23
}

var index = 0
for (i in range) {
index += words[i].length + 1
}

decryptedPhrase = decryptedString.substring(0, index - 1)
passphrase = decryptedString.substring(index)

} else {
cipherWrapper.decrypt(encryptedPhrase, privateKey)
decryptedPhrase = cipherWrapper.decrypt(encryptedPhrase, privateKey)
}

return Pair(decryptedData, passphrase)
return Pair(decryptedPhrase, passphrase)
}

@Deprecated("TODO: Remove this method in new app")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import java.util.*

class StringFormat {
companion object {
fun getWordCount(word : String) : Int {
return word.split(" ".toRegex()).size
}

fun getFormattedDate(str: String): String {
val formatter = DateTimeFormatter.ofPattern("MMM dd, uuuu", Locale.ENGLISH)
.withZone(ZoneId.of("UTC"))
Expand Down