Use secure passphrase generator and allow ikey setup on existing accounts

This commit is contained in:
Paul Schaub 2020-11-29 23:36:38 +01:00
parent 3cbe527959
commit a41e2d34ab
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
9 changed files with 92 additions and 17 deletions

View File

@ -8,7 +8,11 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
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.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 java.util.UUID;
@ -17,7 +21,7 @@ import butterknife.BindView;
import butterknife.ButterKnife;
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";
@ -54,6 +58,34 @@ public class AccountDetailsActivity extends AppCompatActivity implements Mercury
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
private class Arguments {
UUID accountId;

View File

@ -24,6 +24,7 @@ import com.google.android.material.card.MaterialCardView;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.android.MercuryImApplication;
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.OpenPgpV4FingerprintFormatter;
import org.mercury_im.messenger.core.util.Optional;
@ -131,11 +132,11 @@ public class AccountDetailsFragment extends Fragment {
viewModel.onRestoreIkeyBackup();
return true;
// case R.id.action_setup_ikey:
// getParentFragmentManager().beginTransaction()
// .replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
// .commit();
// return true;
case R.id.action_setup_ikey:
getParentFragmentManager().beginTransaction()
.replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
.commit();
return true;
}
return super.onOptionsItemSelected(item);
}

View File

@ -26,7 +26,7 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import lombok.Getter;
public class AddAccountActivity extends AppCompatActivity {
public class AddAccountActivity extends AppCompatActivity implements IkeySetupNavigator {
@BindView(R.id.viewpager)
ViewPager2 viewPager;
@ -58,6 +58,7 @@ public class AddAccountActivity extends AppCompatActivity {
}
}
@Override
public void setupIkey(UUID accountId) {
int nextPos = pagerAdapter.getItemCount();
pagerAdapter.getFragments().put(nextPos, IkeyBackupRestoreOrSkipFragment.newInstance(accountId));
@ -65,6 +66,7 @@ public class AddAccountActivity extends AppCompatActivity {
viewPager.setCurrentItem(nextPos);
}
@Override
public void restoreSuccessful(UUID accountId) {
int nextPos = pagerAdapter.getItemCount();
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));
@ -72,6 +74,7 @@ public class AddAccountActivity extends AppCompatActivity {
viewPager.setCurrentItem(nextPos);
}
@Override
public void generateIkeyBackup(UUID accountId) {
int nextPos = pagerAdapter.getItemCount();
pagerAdapter.getFragments().put(nextPos, IkeyBackupCreationFragment.newInstance(accountId));
@ -79,6 +82,7 @@ public class AddAccountActivity extends AppCompatActivity {
viewPager.setCurrentItem(nextPos);
}
@Override
public void displayInfo(UUID accountId) {
int nextPos = pagerAdapter.getItemCount();
pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId));

View File

@ -62,7 +62,7 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment {
restoreButton.setOnClickListener(v -> onRestore());
regenerateButton.setOnClickListener(v ->
((AddAccountActivity) getActivity()).generateIkeyBackup(accountId));
((IkeySetupNavigator) getActivity()).generateIkeyBackup(accountId));
viewModel.getPassphraseError().observe(this, opt -> {
if (opt.isPresent()) {
@ -75,7 +75,7 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment {
String backupCode = backupCodeEditText.getText().toString();
if (viewModel.restoreBackup(backupCode)) {
((AddAccountActivity) getActivity()).restoreSuccessful(accountId);
((IkeySetupNavigator) getActivity()).restoreSuccessful(accountId);
}
}

View File

@ -59,7 +59,7 @@ public class IkeyKeyInfoFragment extends Fragment {
viewModel.init(accountId);
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());
}
}

View File

@ -62,10 +62,10 @@ public class IkeySetupFragment extends Fragment {
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(opt -> {
if (opt.isPresent()) {
((AddAccountActivity) getActivity()).setupIkey(accountId);
((IkeySetupNavigator) getActivity()).setupIkey(accountId);
} else {
viewModel.generateIdentityKey();
((AddAccountActivity) getActivity()).displayInfo(accountId);
((IkeySetupNavigator) getActivity()).displayInfo(accountId);
}
})
.subscribe();

View File

@ -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);
}

View File

@ -76,6 +76,33 @@ public class MercuryOpenPgpManager {
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
oxManager.setOpenPgpProvider(provider);
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;
try {
if (!oxManager.hasSecretKeysAvailable()) {

View File

@ -1,9 +1,7 @@
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.OxPlusIkeyKeyGenerationStrategy;
import org.mercury_im.messenger.core.crypto.SecureRandomSecretKeyBackupPassphraseGenerator;
import javax.inject.Singleton;
@ -16,7 +14,6 @@ public class OpenPgpModule {
@Singleton
@Provides
static OpenPgpSecretKeyBackupPassphraseGenerator provideSecretKeyBackupPassphraseGenerator() {
// TODO: THIS MUST NEVER MAKE IT TO PRODUCTION!!!
return new InsecureStaticSecretKeyBackupPassphraseGenerator();
return new SecureRandomSecretKeyBackupPassphraseGenerator();
}
}