make sure omemo sessions are verified if the the respective config flag is set
This commit is contained in:
parent
9544b994dc
commit
e2324209ed
|
@ -1234,6 +1234,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
throw new CryptoFailedException(String.format("No session found for %d", deviceId));
|
throw new CryptoFailedException(String.format("No session found for %d", deviceId));
|
||||||
}
|
}
|
||||||
|
if (Config.REQUIRE_RTP_VERIFICATION) {
|
||||||
|
requireVerification(session);
|
||||||
|
}
|
||||||
final ImmutableMap.Builder<String, RtpContentMap.DescriptionTransport> descriptionTransportBuilder = new ImmutableMap.Builder<>();
|
final ImmutableMap.Builder<String, RtpContentMap.DescriptionTransport> descriptionTransportBuilder = new ImmutableMap.Builder<>();
|
||||||
final OmemoVerification omemoVerification = new OmemoVerification();
|
final OmemoVerification omemoVerification = new OmemoVerification();
|
||||||
omemoVerification.setDeviceId(deviceId);
|
omemoVerification.setDeviceId(deviceId);
|
||||||
|
@ -1283,6 +1286,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
final Element encrypted = child.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
|
final Element encrypted = child.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
|
||||||
final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, from.asBareJid());
|
final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, from.asBareJid());
|
||||||
final XmppAxolotlSession session = getReceivingSession(xmppAxolotlMessage);
|
final XmppAxolotlSession session = getReceivingSession(xmppAxolotlMessage);
|
||||||
|
if (Config.REQUIRE_RTP_VERIFICATION) {
|
||||||
|
requireVerification(session);
|
||||||
|
}
|
||||||
final XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintext = xmppAxolotlMessage.decrypt(session, getOwnDeviceId());
|
final XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintext = xmppAxolotlMessage.decrypt(session, getOwnDeviceId());
|
||||||
final Integer preKeyId = session.getPreKeyIdAndReset();
|
final Integer preKeyId = session.getPreKeyIdAndReset();
|
||||||
if (preKeyId != null) {
|
if (preKeyId != null) {
|
||||||
|
@ -1299,6 +1305,16 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
return new OmemoVerifiedPayload<>(omemoVerification, transportInfo);
|
return new OmemoVerifiedPayload<>(omemoVerification, transportInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void requireVerification(final XmppAxolotlSession session) {
|
||||||
|
if (session.getTrust().isVerified()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new NotVerifiedException(String.format(
|
||||||
|
"session with %s was not verified",
|
||||||
|
session.getFingerprint()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public void prepareKeyTransportMessage(final Conversation conversation, final OnMessageCreatedCallback onMessageCreatedCallback) {
|
public void prepareKeyTransportMessage(final Conversation conversation, final OnMessageCreatedCallback onMessageCreatedCallback) {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1690,4 +1706,12 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class NotVerifiedException extends SecurityException {
|
||||||
|
|
||||||
|
public NotVerifiedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -762,9 +762,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
} catch (final WebRTCWrapper.InitializationException e) {
|
} catch (final WebRTCWrapper.InitializationException e) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to initialize WebRTC");
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to initialize WebRTC");
|
||||||
webRTCWrapper.close();
|
webRTCWrapper.close();
|
||||||
sendJingleMessage("retract", id.with.asBareJid());
|
sendRetract(Reason.ofException(e));
|
||||||
transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE);
|
|
||||||
this.finish();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -776,22 +774,27 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to sendSessionInitiate", Throwables.getRootCause(e));
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to sendSessionInitiate", Throwables.getRootCause(e));
|
||||||
webRTCWrapper.close();
|
webRTCWrapper.close();
|
||||||
|
final Reason reason = Reason.ofException(e);
|
||||||
if (isInState(targetState)) {
|
if (isInState(targetState)) {
|
||||||
sendSessionTerminate(Reason.FAILED_APPLICATION);
|
sendSessionTerminate(reason);
|
||||||
} else {
|
} else {
|
||||||
sendJingleMessage("retract", id.with.asBareJid());
|
sendRetract(reason);
|
||||||
transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE);
|
|
||||||
this.finish();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendRetract(final Reason reason) {
|
||||||
|
//TODO embed reason into retract
|
||||||
|
sendJingleMessage("retract", id.with.asBareJid());
|
||||||
|
transitionOrThrow(reasonToState(reason));
|
||||||
|
this.finish();
|
||||||
|
}
|
||||||
|
|
||||||
private void sendSessionInitiate(final RtpContentMap rtpContentMap, final State targetState) {
|
private void sendSessionInitiate(final RtpContentMap rtpContentMap, final State targetState) {
|
||||||
this.initiatorRtpContentMap = rtpContentMap;
|
this.initiatorRtpContentMap = rtpContentMap;
|
||||||
this.transitionOrThrow(targetState);
|
|
||||||
//TODO do on background thread?
|
|
||||||
final RtpContentMap outgoingContentMap = encryptSessionInitiate(rtpContentMap);
|
final RtpContentMap outgoingContentMap = encryptSessionInitiate(rtpContentMap);
|
||||||
final JinglePacket sessionInitiate = outgoingContentMap.toJinglePacket(JinglePacket.Action.SESSION_INITIATE, id.sessionId);
|
final JinglePacket sessionInitiate = outgoingContentMap.toJinglePacket(JinglePacket.Action.SESSION_INITIATE, id.sessionId);
|
||||||
|
this.transitionOrThrow(targetState);
|
||||||
send(sessionInitiate);
|
send(sessionInitiate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ package eu.siacs.conversations.xmpp.jingle.stanzas;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
|
||||||
import eu.siacs.conversations.xmpp.jingle.RtpContentMap;
|
import eu.siacs.conversations.xmpp.jingle.RtpContentMap;
|
||||||
|
|
||||||
public enum Reason {
|
public enum Reason {
|
||||||
|
@ -51,4 +53,12 @@ public enum Reason {
|
||||||
return FAILED_APPLICATION;
|
return FAILED_APPLICATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Reason ofException(final Exception e) {
|
||||||
|
final Throwable root = Throwables.getRootCause(e);
|
||||||
|
if (root instanceof RuntimeException) {
|
||||||
|
return of((RuntimeException) root);
|
||||||
|
}
|
||||||
|
return FAILED_APPLICATION;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue