mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 20:08:01 +01:00
Define identity key check endpoint in keys anonymous service
This commit is contained in:
@@ -20,4 +20,11 @@ public class IdentityTypeUtil {
|
||||
case IDENTITY_TYPE_UNSPECIFIED, UNRECOGNIZED -> throw Status.INVALID_ARGUMENT.asRuntimeException();
|
||||
};
|
||||
}
|
||||
|
||||
public static org.signal.chat.common.IdentityType toGrpcIdentityType(final IdentityType identityType) {
|
||||
return switch (identityType) {
|
||||
case ACI -> org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI;
|
||||
case PNI -> org.signal.chat.common.IdentityType.IDENTITY_TYPE_PNI;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,24 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.grpc;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.Status;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import org.signal.chat.keys.CheckIdentityKeyRequest;
|
||||
import org.signal.chat.keys.CheckIdentityKeyResponse;
|
||||
import org.signal.chat.keys.GetPreKeysAnonymousRequest;
|
||||
import org.signal.chat.keys.GetPreKeysResponse;
|
||||
import org.signal.chat.keys.ReactorKeysAnonymousGrpc;
|
||||
import org.signal.libsignal.protocol.IdentityKey;
|
||||
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
public class KeysAnonymousGrpcService extends ReactorKeysAnonymousGrpc.KeysAnonymousImplBase {
|
||||
|
||||
@@ -38,4 +47,35 @@ public class KeysAnonymousGrpcService extends ReactorKeysAnonymousGrpc.KeysAnony
|
||||
? KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), request.getRequest().getDeviceId(), keysManager)
|
||||
: Mono.error(Status.UNAUTHENTICATED.asException()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<CheckIdentityKeyResponse> checkIdentityKeys(final Flux<CheckIdentityKeyRequest> requests) {
|
||||
return requests
|
||||
.map(request -> Tuples.of(ServiceIdentifierUtil.fromGrpcServiceIdentifier(request.getTargetIdentifier()),
|
||||
request.getFingerprint().toByteArray()))
|
||||
.flatMap(serviceIdentifierAndFingerprint -> Mono.fromFuture(
|
||||
() -> accountsManager.getByServiceIdentifierAsync(serviceIdentifierAndFingerprint.getT1()))
|
||||
.flatMap(Mono::justOrEmpty)
|
||||
.filter(account -> !fingerprintMatches(account.getIdentityKey(serviceIdentifierAndFingerprint.getT1()
|
||||
.identityType()), serviceIdentifierAndFingerprint.getT2()))
|
||||
.map(account -> CheckIdentityKeyResponse.newBuilder()
|
||||
.setTargetIdentifier(
|
||||
ServiceIdentifierUtil.toGrpcServiceIdentifier(serviceIdentifierAndFingerprint.getT1()))
|
||||
.setIdentityKey(ByteString.copyFrom(account.getIdentityKey(serviceIdentifierAndFingerprint.getT1()
|
||||
.identityType()).serialize()))
|
||||
.build())
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean fingerprintMatches(final IdentityKey identityKey, final byte[] fingerprint) {
|
||||
final byte[] digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA-256").digest(identityKey.serialize());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// SHA-256 should always be supported as an algorithm
|
||||
throw new AssertionError("All Java implementations must support the SHA-256 message digest");
|
||||
}
|
||||
|
||||
return Arrays.equals(digest, 0, 4, fingerprint, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.grpc;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.Status;
|
||||
import java.util.UUID;
|
||||
import org.signal.chat.common.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
@@ -31,4 +33,11 @@ public class ServiceIdentifierUtil {
|
||||
case PNI -> new PniServiceIdentifier(uuid);
|
||||
};
|
||||
}
|
||||
|
||||
public static org.signal.chat.common.ServiceIdentifier toGrpcServiceIdentifier(final ServiceIdentifier serviceIdentifier) {
|
||||
return org.signal.chat.common.ServiceIdentifier.newBuilder()
|
||||
.setIdentityType(IdentityTypeUtil.toGrpcIdentityType(serviceIdentifier.identityType()))
|
||||
.setUuid(UUIDUtil.toByteString(serviceIdentifier.uuid()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user