Publish correct superordinate key

This commit is contained in:
Paul Schaub 2020-12-18 16:33:23 +01:00
parent 1e3c98abea
commit c4e672cc21
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
6 changed files with 38 additions and 44 deletions

View file

@ -137,6 +137,9 @@ public class AccountDetailsFragment extends Fragment {
.replace(R.id.fragment, IkeySetupFragment.newInstance(accountId)) .replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
.commit(); .commit();
return true; return true;
case R.id.action_publish_ikey_element:
sendIkeyElement();
return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

View file

@ -9,38 +9,15 @@ import androidx.lifecycle.ViewModel;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.PresenceEventListener;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterGroup;
import org.jivesoftware.smackx.ikey.util.IkeyTrust;
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.MercuryImApplication;
import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable;
import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel; import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel;
import org.mercury_im.messenger.core.Messenger;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.crypto.ikey.IkeyRepository;
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.core.util.Tuple;
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
import org.mercury_im.messenger.core.viewmodel.contact.ContactDetailViewModel; import org.mercury_im.messenger.core.viewmodel.contact.ContactDetailViewModel;
import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem; import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem;
import org.mercury_im.messenger.entity.chat.Chat;
import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable;
import org.mercury_im.messenger.core.util.CombinedPresenceListener;
import org.mercury_im.messenger.entity.contact.Peer;
import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.OpenPgpV4Fingerprint;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -49,8 +26,6 @@ import javax.inject.Inject;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.Single; import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.BiFunction;
public class AndroidContactDetailViewModel extends ViewModel implements MercuryAndroidViewModel<ContactDetailViewModel> { public class AndroidContactDetailViewModel extends ViewModel implements MercuryAndroidViewModel<ContactDetailViewModel> {
@ -99,12 +74,6 @@ public class AndroidContactDetailViewModel extends ViewModel implements MercuryA
return contactAddress; return contactAddress;
} }
@Override
protected void onCleared() {
super.onCleared();
commonViewModel.dispose();
}
public LiveData<UUID> getAccountId() { public LiveData<UUID> getAccountId() {
return contactAccountId; return contactAccountId;
} }

View file

@ -20,6 +20,7 @@ import javax.inject.Inject;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import lombok.Value; import lombok.Value;
@ -29,6 +30,8 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
private AndroidContactDetailViewModel androidContactDetailViewModel; private AndroidContactDetailViewModel androidContactDetailViewModel;
private UUID peerId; private UUID peerId;
Disposable disposable;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -40,7 +43,7 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
androidContactDetailViewModel = new ViewModelProvider(this).get(AndroidContactDetailViewModel.class); androidContactDetailViewModel = new ViewModelProvider(this).get(AndroidContactDetailViewModel.class);
bindUiComponents(); bindUiComponents();
androidContactDetailViewModel.init(peerId) disposable = androidContactDetailViewModel.init(peerId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(); .subscribe();
@ -65,4 +68,10 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
private class Arguments { private class Arguments {
UUID peerId; UUID peerId;
} }
@Override
protected void onDestroy() {
super.onDestroy();
disposable.dispose();
}
} }

View file

@ -27,4 +27,8 @@
android:id="@+id/action_setup_ikey" android:id="@+id/action_setup_ikey"
android:title="Ikey Setup" /> android:title="Ikey Setup" />
<item
android:id="@+id/action_publish_ikey_element"
android:title="Publish Ikey Element" />
</menu> </menu>

View file

@ -163,11 +163,19 @@ public final class IkeyManager extends Manager {
return new IkeyElement(mechanism.getType(), superordinateElement, signedElement, proofElement); return new IkeyElement(mechanism.getType(), superordinateElement, signedElement, proofElement);
} }
public void publishIkeyElement(IkeyElement ikeyElement) public void storeAndPublishElement(IkeyElement ikeyElement)
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
SmackException.NotConnectedException, SmackException.NoResponseException { SmackException.NotConnectedException, SmackException.NoResponseException, IOException, PGPException {
store.storeIkeyRecord(connection().getUser().asEntityBareJid(), elementToRecord(ikeyElement));
publishIkeyElement(ikeyElement);
}
public void publishIkeyElement(IkeyElement element)
throws InterruptedException, PubSubException.NotALeafNodeException,
XMPPException.XMPPErrorException, SmackException.NotConnectedException,
SmackException.NoResponseException {
PepManager.getInstanceFor(connection()) PepManager.getInstanceFor(connection())
.publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(ikeyElement)); .publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(element));
} }
public IkeyElement fetchIkeyElementOf(EntityBareJid jid) public IkeyElement fetchIkeyElementOf(EntityBareJid jid)
@ -201,7 +209,8 @@ public final class IkeyManager extends Manager {
throws IOException, UnsupportedSignatureAlgorithmException, PGPException { throws IOException, UnsupportedSignatureAlgorithmException, PGPException {
IkeyRecord newRecord = elementToRecord(element); IkeyRecord newRecord = elementToRecord(element);
if (isFromTheFuture(newRecord)) { if (isFromTheFuture(newRecord)) {
LOGGER.log(Level.WARNING, "Received ikey element appears to be from the future: " + element.getSignedElement().getChildElement().getTimestamp()); LOGGER.log(Level.WARNING, "Received ikey element appears to be from the future: " +
newRecord.getTimestamp());
return; return;
} }
@ -307,9 +316,9 @@ public final class IkeyManager extends Manager {
} }
private static boolean isFromTheFuture(IkeyRecord record) { private static boolean isFromTheFuture(IkeyRecord record) {
Date elementTimestamp = record.getTimestamp(); Date timestamp = record.getTimestamp();
Date now = new Date(); Date now = new Date();
return elementTimestamp.after(now); return timestamp.after(now);
} }
private boolean existsSameOrNewerRecord(IkeyRecord record) throws IOException { private boolean existsSameOrNewerRecord(IkeyRecord record) throws IOException {

View file

@ -1,6 +1,5 @@
package org.mercury_im.messenger.core.viewmodel.account.detail; package org.mercury_im.messenger.core.viewmodel.account.detail;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.ikey.IkeyManager; import org.jivesoftware.smackx.ikey.IkeyManager;
@ -88,7 +87,7 @@ public class AccountDetailsViewModel implements MercuryViewModel {
IkeyElement ikeyElement = syncCreateIkeyElement(accountId); IkeyElement ikeyElement = syncCreateIkeyElement(accountId);
IkeyManager ikeyManager = IkeyManager.getInstanceFor(connectionManager.getConnection(accountId).getConnection()); IkeyManager ikeyManager = IkeyManager.getInstanceFor(connectionManager.getConnection(accountId).getConnection());
ikeyManager.publishIkeyElement(ikeyElement); ikeyManager.storeAndPublishElement(ikeyElement);
}) })
.compose(schedulers.executeUiSafeCompletable()) .compose(schedulers.executeUiSafeCompletable())
.subscribe( .subscribe(
@ -96,7 +95,7 @@ public class AccountDetailsViewModel implements MercuryViewModel {
e -> LOGGER.log(Level.SEVERE, "Error publishing ikey element:", e))); e -> LOGGER.log(Level.SEVERE, "Error publishing ikey element:", e)));
} }
private IkeyElement syncCreateIkeyElement(UUID accountId) throws URISyntaxException, PGPException, IOException { private IkeyElement syncCreateIkeyElement(UUID accountId) throws URISyntaxException, IOException {
MercuryConnection connection = connectionManager.getConnection(accountId); MercuryConnection connection = connectionManager.getConnection(accountId);
IkeyManager ikeyManager = ikeyInitializer.initFor(connection); IkeyManager ikeyManager = ikeyInitializer.initFor(connection);
@ -124,8 +123,9 @@ public class AccountDetailsViewModel implements MercuryViewModel {
subordinateElements.add(new SubordinateElement("urn:xmpp:openpgp:0", u, fp.toString())); subordinateElements.add(new SubordinateElement("urn:xmpp:openpgp:0", u, fp.toString()));
} }
PGPSecretKeyRing secretKeys = openPgpRepository.loadSecretKeysOf(accountId, account.getJid()) PGPSecretKeyRing secretKeys = ikeyRepository.loadSecretKey(accountId)
.blockingGet().getSecretKeyRing(localFp.getKeyId()); .blockingFirst(new Optional<>())
.getItem();
IkeyElement ikeyElement = ikeyManager.createOxIkeyElement(secretKeys, IkeyElement ikeyElement = ikeyManager.createOxIkeyElement(secretKeys,
new UnprotectedKeysProtector(), subordinateElements.toArray(new SubordinateElement[]{})); new UnprotectedKeysProtector(), subordinateElements.toArray(new SubordinateElement[]{}));