Add support for call link epochs.

This commit is contained in:
emir-signal
2025-07-03 15:07:34 -04:00
committed by Alex Hart
parent 5d0f71e02c
commit b42dcece48
34 changed files with 211 additions and 71 deletions

View File

@@ -70,7 +70,7 @@ class CallLinkPreJoinActionProcessor(
serverPublicParams.endorsementPublicKey,
callLinkAuthCredentialPresentation.serialize(),
callLinkRootKey,
null,
callLink.credentials.epoch,
callLink.credentials.adminPassBytes,
ByteArray(0),
AUDIO_LEVELS_INTERVAL,

View File

@@ -25,6 +25,7 @@ import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams;
import org.signal.libsignal.zkgroup.groups.GroupIdentifier;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallLinkEpoch;
import org.signal.ringrtc.CallLinkRootKey;
import org.signal.ringrtc.CallManager;
import org.signal.ringrtc.GroupCall;
@@ -406,6 +407,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
}
CallLinkRootKey callLinkRootKey = new CallLinkRootKey(callLink.getCredentials().getLinkKeyBytes());
CallLinkEpoch callLinkEpoch = callLink.getCredentials().getEpoch();
GenericServerPublicParams genericServerPublicParams = new GenericServerPublicParams(AppDependencies.getSignalServiceNetworkAccess()
.getConfiguration()
.getGenericServerPublicParams());
@@ -417,7 +419,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
CallLinkSecretParams.deriveFromRootKey(callLinkRootKey.getKeyBytes())
);
callManager.peekCallLinkCall(SignalStore.internal().getGroupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, null, peekInfo -> {
callManager.peekCallLinkCall(SignalStore.internal().getGroupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, callLinkEpoch, peekInfo -> {
PeekInfo info = peekInfo.getValue();
if (info == null) {
Log.w(TAG, "Failed to get peek info: " + peekInfo.getStatus());

View File

@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.service.webrtc.links
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.signal.ringrtc.CallLinkEpoch
import org.signal.ringrtc.CallLinkRootKey
/**
@@ -15,6 +16,7 @@ import org.signal.ringrtc.CallLinkRootKey
@Parcelize
data class CallLinkCredentials(
val linkKeyBytes: ByteArray,
val epochBytes: ByteArray?,
val adminPassBytes: ByteArray?
) : Parcelable {
@@ -22,6 +24,10 @@ data class CallLinkCredentials(
CallLinkRoomId.fromCallLinkRootKey(CallLinkRootKey(linkKeyBytes))
}
val epoch: CallLinkEpoch? by lazy {
epochBytes?.let { CallLinkEpoch.fromBytes(it) }
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
@@ -35,6 +41,12 @@ data class CallLinkCredentials(
} else if (other.adminPassBytes != null) {
return false
}
if (epochBytes != null) {
if (other.epochBytes == null) return false
if (!epochBytes.contentEquals(other.epochBytes)) return false
} else if (other.epochBytes != null) {
return false
}
return true
}
@@ -52,6 +64,7 @@ data class CallLinkCredentials(
fun generate(): CallLinkCredentials {
return CallLinkCredentials(
CallLinkRootKey.generate().keyBytes,
null,
CallLinkRootKey.generateAdminPasskey()
)
}

View File

@@ -120,9 +120,10 @@ class SignalCallLinkManager(
) { result ->
if (result.isSuccess) {
Log.d(TAG, "Successfully created call link.")
val epoch = result.value!!.epoch
emitter.onSuccess(
CreateCallLinkResult.Success(
credentials = CallLinkCredentials(rootKey.keyBytes, adminPassKey),
credentials = CallLinkCredentials(rootKey.keyBytes, epoch?.bytes, adminPassKey),
state = result.value!!.toAppState()
)
)
@@ -142,7 +143,7 @@ class SignalCallLinkManager(
SignalStore.internal.groupCallingServer,
requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes).serialize(),
CallLinkRootKey(credentials.linkKeyBytes),
null
credentials.epoch
) {
if (it.isSuccess) {
emitter.onSuccess(ReadCallLinkResult.Success(it.value!!.toAppState()))
@@ -169,7 +170,7 @@ class SignalCallLinkManager(
SignalStore.internal.groupCallingServer,
credentialPresentation.serialize(),
CallLinkRootKey(credentials.linkKeyBytes),
null,
credentials.epoch,
credentials.adminPassBytes,
name
) { result ->
@@ -197,7 +198,7 @@ class SignalCallLinkManager(
SignalStore.internal.groupCallingServer,
credentialPresentation.serialize(),
CallLinkRootKey(credentials.linkKeyBytes),
null,
credentials.epoch,
credentials.adminPassBytes,
restrictions
) { result ->
@@ -224,7 +225,7 @@ class SignalCallLinkManager(
SignalStore.internal.groupCallingServer,
credentialPresentation.serialize(),
CallLinkRootKey(credentials.linkKeyBytes),
null,
credentials.epoch,
credentials.adminPassBytes
) { result ->
if (result.isSuccess && result.value == true) {