diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/GroupSendTokenUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/GroupSendTokenUtil.java index b021388f3..60380a932 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/GroupSendTokenUtil.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/GroupSendTokenUtil.java @@ -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 checkGroupSendToken(final ByteString serializedGroupSendToken, List serviceIdentifiers) { + public void checkGroupSendToken(final ByteString serializedGroupSendToken, + final List serviceIdentifiers) throws StatusException { + try { final GroupSendFullToken token = new GroupSendFullToken(serializedGroupSendToken.toByteArray()); final List 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(); } } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysAnonymousGrpcService.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysAnonymousGrpcService.java index 24095659a..2bbb19239 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysAnonymousGrpcService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysAnonymousGrpcService.java @@ -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()); }; } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ProfileAnonymousGrpcService.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ProfileAnonymousGrpcService.java index 48c411b02..1814173d1 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ProfileAnonymousGrpcService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ProfileAnonymousGrpcService.java @@ -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 = 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());