Make the utility method for checking group send credentials blocking

This commit is contained in:
Jon Chambers 2025-03-19 16:59:29 -04:00 committed by Jon Chambers
parent 1f1e4c72ec
commit 5a7f4d8381
3 changed files with 29 additions and 14 deletions

View File

@ -7,7 +7,7 @@ package org.whispersystems.textsecuregcm.grpc;
import com.google.protobuf.ByteString;
import io.grpc.Status;
import io.grpc.StatusException;
import java.time.Clock;
import java.util.List;
import org.signal.libsignal.protocol.ServiceId;
@ -18,8 +18,6 @@ import org.signal.libsignal.zkgroup.groupsend.GroupSendDerivedKeyPair;
import org.signal.libsignal.zkgroup.groupsend.GroupSendFullToken;
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
import reactor.core.publisher.Mono;
public class GroupSendTokenUtil {
private final ServerSecretParams serverSecretParams;
@ -30,16 +28,17 @@ public class GroupSendTokenUtil {
this.clock = clock;
}
public Mono<Void> checkGroupSendToken(final ByteString serializedGroupSendToken, List<ServiceIdentifier> serviceIdentifiers) {
public void checkGroupSendToken(final ByteString serializedGroupSendToken,
final List<ServiceIdentifier> serviceIdentifiers) throws StatusException {
try {
final GroupSendFullToken token = new GroupSendFullToken(serializedGroupSendToken.toByteArray());
final List<ServiceId> serviceIds = serviceIdentifiers.stream().map(ServiceIdentifier::toLibsignal).toList();
token.verify(serviceIds, clock.instant(), GroupSendDerivedKeyPair.forExpiration(token.getExpiration(), serverSecretParams));
return Mono.empty();
} catch (InvalidInputException e) {
return Mono.error(Status.INVALID_ARGUMENT.asException());
} catch (final InvalidInputException e) {
throw Status.INVALID_ARGUMENT.asException();
} catch (VerificationFailedException e) {
return Mono.error(Status.UNAUTHENTICATED.asException());
throw Status.UNAUTHENTICATED.asException();
}
}
}

View File

@ -13,6 +13,7 @@ import java.time.Clock;
import java.util.Arrays;
import java.util.List;
import io.grpc.StatusException;
import org.signal.chat.keys.CheckIdentityKeyRequest;
import org.signal.chat.keys.CheckIdentityKeyResponse;
import org.signal.chat.keys.GetPreKeysAnonymousRequest;
@ -52,16 +53,24 @@ public class KeysAnonymousGrpcService extends ReactorKeysAnonymousGrpc.KeysAnony
: KeysGrpcHelper.ALL_DEVICES;
return switch (request.getAuthorizationCase()) {
case GROUP_SEND_TOKEN ->
groupSendTokenUtil.checkGroupSendToken(request.getGroupSendToken(), List.of(serviceIdentifier))
.then(lookUpAccount(serviceIdentifier, Status.NOT_FOUND))
case GROUP_SEND_TOKEN -> {
try {
groupSendTokenUtil.checkGroupSendToken(request.getGroupSendToken(), List.of(serviceIdentifier));
yield lookUpAccount(serviceIdentifier, Status.NOT_FOUND)
.flatMap(targetAccount -> KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), deviceId, keysManager));
} catch (final StatusException e) {
yield Mono.error(e);
}
}
case UNIDENTIFIED_ACCESS_KEY ->
lookUpAccount(serviceIdentifier, Status.UNAUTHENTICATED)
.flatMap(targetAccount ->
UnidentifiedAccessUtil.checkUnidentifiedAccess(targetAccount, request.getUnidentifiedAccessKey().toByteArray())
? KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), deviceId, keysManager)
: Mono.error(Status.UNAUTHENTICATED.asException()));
default -> Mono.error(Status.INVALID_ARGUMENT.asException());
};
}

View File

@ -10,6 +10,7 @@ import io.grpc.Status;
import java.time.Clock;
import java.util.List;
import io.grpc.StatusException;
import org.signal.chat.profile.CredentialType;
import org.signal.chat.profile.GetExpiringProfileKeyCredentialAnonymousRequest;
import org.signal.chat.profile.GetExpiringProfileKeyCredentialResponse;
@ -59,11 +60,17 @@ public class ProfileAnonymousGrpcService extends ReactorProfileAnonymousGrpc.Pro
}
final Mono<Account> account = switch (request.getAuthenticationCase()) {
case GROUP_SEND_TOKEN ->
groupSendTokenUtil.checkGroupSendToken(request.getGroupSendToken(), List.of(targetIdentifier))
.then(Mono.fromFuture(() -> accountsManager.getByServiceIdentifierAsync(targetIdentifier)))
case GROUP_SEND_TOKEN -> {
try {
groupSendTokenUtil.checkGroupSendToken(request.getGroupSendToken(), List.of(targetIdentifier));
yield Mono.fromFuture(() -> accountsManager.getByServiceIdentifierAsync(targetIdentifier))
.flatMap(Mono::justOrEmpty)
.switchIfEmpty(Mono.error(Status.NOT_FOUND.asException()));
} catch (final StatusException e) {
yield Mono.error(e);
}
}
case UNIDENTIFIED_ACCESS_KEY ->
getTargetAccountAndValidateUnidentifiedAccess(targetIdentifier, request.getUnidentifiedAccessKey().toByteArray());
default -> Mono.error(Status.INVALID_ARGUMENT.asException());