Use secure passphrase generator and allow ikey setup on existing accounts
This commit is contained in:
parent
3cbe527959
commit
a41e2d34ab
|
@ -8,7 +8,11 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
import org.mercury_im.messenger.R;
|
import org.mercury_im.messenger.R;
|
||||||
|
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
||||||
import org.mercury_im.messenger.android.ui.MercuryActivity;
|
import org.mercury_im.messenger.android.ui.MercuryActivity;
|
||||||
|
import org.mercury_im.messenger.android.ui.account.login.IkeyBackupRestoreOrSkipFragment;
|
||||||
|
import org.mercury_im.messenger.android.ui.account.login.IkeyKeyInfoFragment;
|
||||||
|
import org.mercury_im.messenger.android.ui.account.login.IkeySetupNavigator;
|
||||||
import org.mercury_im.messenger.android.util.ArgumentUtils;
|
import org.mercury_im.messenger.android.util.ArgumentUtils;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -17,7 +21,7 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
public class AccountDetailsActivity extends AppCompatActivity implements MercuryActivity {
|
public class AccountDetailsActivity extends AppCompatActivity implements MercuryActivity, IkeySetupNavigator {
|
||||||
|
|
||||||
public static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
|
public static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
|
||||||
|
|
||||||
|
@ -54,6 +58,34 @@ public class AccountDetailsActivity extends AppCompatActivity implements Mercury
|
||||||
return new Arguments(accountId);
|
return new Arguments(accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupIkey(UUID accountId) {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragment, IkeyBackupRestoreOrSkipFragment.newInstance(accountId), "setup_ikey")
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreSuccessful(UUID accountId) {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragment, IkeyKeyInfoFragment.newInstance(accountId), "ikey_success")
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateIkeyBackup(UUID accountId) {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragment, IkeyBackupCreationFragment.newInstance(accountId), "backup")
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayInfo(UUID accountId) {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragment, IkeyKeyInfoFragment.newInstance(accountId), "info")
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
private class Arguments {
|
private class Arguments {
|
||||||
UUID accountId;
|
UUID accountId;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.android.material.card.MaterialCardView;
|
||||||
import org.mercury_im.messenger.R;
|
import org.mercury_im.messenger.R;
|
||||||
import org.mercury_im.messenger.android.MercuryImApplication;
|
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||||
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
||||||
|
import org.mercury_im.messenger.android.ui.account.login.IkeySetupFragment;
|
||||||
import org.mercury_im.messenger.android.ui.openpgp.ToggleableFingerprintsAdapter;
|
import org.mercury_im.messenger.android.ui.openpgp.ToggleableFingerprintsAdapter;
|
||||||
import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter;
|
import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter;
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
@ -131,11 +132,11 @@ public class AccountDetailsFragment extends Fragment {
|
||||||
viewModel.onRestoreIkeyBackup();
|
viewModel.onRestoreIkeyBackup();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// case R.id.action_setup_ikey:
|
case R.id.action_setup_ikey:
|
||||||
// getParentFragmentManager().beginTransaction()
|
getParentFragmentManager().beginTransaction()
|
||||||
// .replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
|
.replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
|
||||||
// .commit();
|
.commit();
|
||||||
// return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class AddAccountActivity extends AppCompatActivity {
|
public class AddAccountActivity extends AppCompatActivity implements IkeySetupNavigator {
|
||||||
|
|
||||||
@BindView(R.id.viewpager)
|
@BindView(R.id.viewpager)
|
||||||
ViewPager2 viewPager;
|
ViewPager2 viewPager;
|
||||||
|
@ -58,6 +58,7 @@ public class AddAccountActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setupIkey(UUID accountId) {
|
public void setupIkey(UUID accountId) {
|
||||||
int nextPos = pagerAdapter.getItemCount();
|
int nextPos = pagerAdapter.getItemCount();
|
||||||
pagerAdapter.getFragments().put(nextPos, IkeyBackupRestoreOrSkipFragment.newInstance(accountId));
|
pagerAdapter.getFragments().put(nextPos, IkeyBackupRestoreOrSkipFragment.newInstance(accountId));
|
||||||
|
@ -65,6 +66,7 @@ public class AddAccountActivity extends AppCompatActivity {
|
||||||
viewPager.setCurrentItem(nextPos);
|
viewPager.setCurrentItem(nextPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void restoreSuccessful(UUID accountId) {
|
public void restoreSuccessful(UUID accountId) {
|
||||||
int nextPos = pagerAdapter.getItemCount();
|
int nextPos = pagerAdapter.getItemCount();
|
||||||
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));
|
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));
|
||||||
|
@ -72,6 +74,7 @@ public class AddAccountActivity extends AppCompatActivity {
|
||||||
viewPager.setCurrentItem(nextPos);
|
viewPager.setCurrentItem(nextPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateIkeyBackup(UUID accountId) {
|
public void generateIkeyBackup(UUID accountId) {
|
||||||
int nextPos = pagerAdapter.getItemCount();
|
int nextPos = pagerAdapter.getItemCount();
|
||||||
pagerAdapter.getFragments().put(nextPos, IkeyBackupCreationFragment.newInstance(accountId));
|
pagerAdapter.getFragments().put(nextPos, IkeyBackupCreationFragment.newInstance(accountId));
|
||||||
|
@ -79,6 +82,7 @@ public class AddAccountActivity extends AppCompatActivity {
|
||||||
viewPager.setCurrentItem(nextPos);
|
viewPager.setCurrentItem(nextPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void displayInfo(UUID accountId) {
|
public void displayInfo(UUID accountId) {
|
||||||
int nextPos = pagerAdapter.getItemCount();
|
int nextPos = pagerAdapter.getItemCount();
|
||||||
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));
|
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment {
|
||||||
|
|
||||||
restoreButton.setOnClickListener(v -> onRestore());
|
restoreButton.setOnClickListener(v -> onRestore());
|
||||||
regenerateButton.setOnClickListener(v ->
|
regenerateButton.setOnClickListener(v ->
|
||||||
((AddAccountActivity) getActivity()).generateIkeyBackup(accountId));
|
((IkeySetupNavigator) getActivity()).generateIkeyBackup(accountId));
|
||||||
|
|
||||||
viewModel.getPassphraseError().observe(this, opt -> {
|
viewModel.getPassphraseError().observe(this, opt -> {
|
||||||
if (opt.isPresent()) {
|
if (opt.isPresent()) {
|
||||||
|
@ -75,7 +75,7 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment {
|
||||||
String backupCode = backupCodeEditText.getText().toString();
|
String backupCode = backupCodeEditText.getText().toString();
|
||||||
|
|
||||||
if (viewModel.restoreBackup(backupCode)) {
|
if (viewModel.restoreBackup(backupCode)) {
|
||||||
((AddAccountActivity) getActivity()).restoreSuccessful(accountId);
|
((IkeySetupNavigator) getActivity()).restoreSuccessful(accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class IkeyKeyInfoFragment extends Fragment {
|
||||||
viewModel.init(accountId);
|
viewModel.init(accountId);
|
||||||
viewModel.getFingerprint().observe(this, f -> fingerprint.setText(f));
|
viewModel.getFingerprint().observe(this, f -> fingerprint.setText(f));
|
||||||
|
|
||||||
buttonBackupIkey.setOnClickListener(v -> ((AddAccountActivity)getActivity()).generateIkeyBackup(accountId));
|
buttonBackupIkey.setOnClickListener(v -> ((IkeySetupNavigator)getActivity()).generateIkeyBackup(accountId));
|
||||||
buttonDone.setOnClickListener(v -> getActivity().finish());
|
buttonDone.setOnClickListener(v -> getActivity().finish());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,10 @@ public class IkeySetupFragment extends Fragment {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnSuccess(opt -> {
|
.doOnSuccess(opt -> {
|
||||||
if (opt.isPresent()) {
|
if (opt.isPresent()) {
|
||||||
((AddAccountActivity) getActivity()).setupIkey(accountId);
|
((IkeySetupNavigator) getActivity()).setupIkey(accountId);
|
||||||
} else {
|
} else {
|
||||||
viewModel.generateIdentityKey();
|
viewModel.generateIdentityKey();
|
||||||
((AddAccountActivity) getActivity()).displayInfo(accountId);
|
((IkeySetupNavigator) getActivity()).displayInfo(accountId);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.mercury_im.messenger.android.ui.account.login;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface IkeySetupNavigator {
|
||||||
|
|
||||||
|
void setupIkey(UUID accountId);
|
||||||
|
|
||||||
|
void restoreSuccessful(UUID accountId);
|
||||||
|
|
||||||
|
void generateIkeyBackup(UUID accountId);
|
||||||
|
|
||||||
|
void displayInfo(UUID accountId);
|
||||||
|
}
|
|
@ -76,6 +76,33 @@ public class MercuryOpenPgpManager {
|
||||||
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
|
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
|
||||||
oxManager.setOpenPgpProvider(provider);
|
oxManager.setOpenPgpProvider(provider);
|
||||||
OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase();
|
OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase();
|
||||||
|
|
||||||
|
|
||||||
|
generateAndPublish(connection, oxManager, passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateAndPublish(MercuryConnection connection, OpenPgpManager oxManager, OpenPgpSecretKeyBackupPassphrase passphrase) {
|
||||||
|
boolean mustGenerate = false;
|
||||||
|
try {
|
||||||
|
if (!oxManager.hasSecretKeysAvailable()) {
|
||||||
|
oxManager.generateAndImportKeyPair(connection.getAccount().getJid());
|
||||||
|
//if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
|
||||||
|
// oxManager.backupSecretKeyToServer(
|
||||||
|
// availableSecretKeys -> availableSecretKeys,
|
||||||
|
// passphrase);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
oxManager.announceSupportAndPublish();
|
||||||
|
OXInstantMessagingManager oximManager = OXInstantMessagingManager.getInstanceFor(connection.getConnection());
|
||||||
|
oximManager.addOxMessageListener(new MercuryMessageStore(connection.getAccount(),
|
||||||
|
peerRepository, directChatRepository, messageRepository, schedulers));
|
||||||
|
oximManager.announceSupportForOxInstantMessaging();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryRestoringAndPublish(MercuryConnection connection, OpenPgpManager oxManager, OpenPgpSecretKeyBackupPassphrase passphrase) {
|
||||||
boolean mustGenerate = false;
|
boolean mustGenerate = false;
|
||||||
try {
|
try {
|
||||||
if (!oxManager.hasSecretKeysAvailable()) {
|
if (!oxManager.hasSecretKeysAvailable()) {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package org.mercury_im.messenger.core.di.module;
|
package org.mercury_im.messenger.core.di.module;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.crypto.InsecureStaticSecretKeyBackupPassphraseGenerator;
|
|
||||||
import org.mercury_im.messenger.core.crypto.LocalOxKeyGenerationStrategy;
|
|
||||||
import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator;
|
import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator;
|
||||||
import org.mercury_im.messenger.core.crypto.OxPlusIkeyKeyGenerationStrategy;
|
import org.mercury_im.messenger.core.crypto.SecureRandomSecretKeyBackupPassphraseGenerator;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -16,7 +14,6 @@ public class OpenPgpModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
static OpenPgpSecretKeyBackupPassphraseGenerator provideSecretKeyBackupPassphraseGenerator() {
|
static OpenPgpSecretKeyBackupPassphraseGenerator provideSecretKeyBackupPassphraseGenerator() {
|
||||||
// TODO: THIS MUST NEVER MAKE IT TO PRODUCTION!!!
|
return new SecureRandomSecretKeyBackupPassphraseGenerator();
|
||||||
return new InsecureStaticSecretKeyBackupPassphraseGenerator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue