Introduce a canonical constant for UAK length

This commit is contained in:
Jon Chambers 2023-10-19 13:28:44 -04:00 committed by Jon Chambers
parent 8ec062fbef
commit ac0c8b1e9a
14 changed files with 86 additions and 74 deletions

View File

@ -20,6 +20,7 @@ import org.signal.libsignal.protocol.IdentityKeyPair;
import org.signal.libsignal.protocol.ecc.ECPublicKey; import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.signal.libsignal.protocol.state.SignedPreKeyRecord; import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.signal.libsignal.protocol.util.KeyHelper; import org.signal.libsignal.protocol.util.KeyHelper;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.Device;
@ -54,7 +55,7 @@ public class TestUser {
// registration id // registration id
final int registrationId = KeyHelper.generateRegistrationId(false); final int registrationId = KeyHelper.generateRegistrationId(false);
// uak // uak
final byte[] unidentifiedAccessKey = RandomUtils.nextBytes(16); final byte[] unidentifiedAccessKey = RandomUtils.nextBytes(UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH);
return new TestUser( return new TestUser(
registrationId, registrationId,

View File

@ -16,7 +16,7 @@ public class CombinedUnidentifiedSenderAccessKeys {
public CombinedUnidentifiedSenderAccessKeys(String header) { public CombinedUnidentifiedSenderAccessKeys(String header) {
try { try {
this.combinedUnidentifiedSenderAccessKeys = Base64.getDecoder().decode(header); this.combinedUnidentifiedSenderAccessKeys = Base64.getDecoder().decode(header);
if (this.combinedUnidentifiedSenderAccessKeys == null || this.combinedUnidentifiedSenderAccessKeys.length != 16) { if (this.combinedUnidentifiedSenderAccessKeys == null || this.combinedUnidentifiedSenderAccessKeys.length != UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH) {
throw new WebApplicationException("Invalid combined unidentified sender access keys", Status.UNAUTHORIZED); throw new WebApplicationException("Invalid combined unidentified sender access keys", Status.UNAUTHORIZED);
} }
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {

View File

@ -14,7 +14,7 @@ public class UnidentifiedAccessChecksum {
public static byte[] generateFor(byte[] unidentifiedAccessKey) { public static byte[] generateFor(byte[] unidentifiedAccessKey) {
try { try {
if (unidentifiedAccessKey.length != 16) { if (unidentifiedAccessKey.length != UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH) {
throw new IllegalArgumentException("Invalid UAK length: " + unidentifiedAccessKey.length); throw new IllegalArgumentException("Invalid UAK length: " + unidentifiedAccessKey.length);
} }

View File

@ -10,6 +10,8 @@ import java.security.MessageDigest;
public class UnidentifiedAccessUtil { public class UnidentifiedAccessUtil {
public static final int UNIDENTIFIED_ACCESS_KEY_LENGTH = 16;
private UnidentifiedAccessUtil() { private UnidentifiedAccessUtil() {
} }

View File

@ -67,6 +67,7 @@ import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.CombinedUnidentifiedSenderAccessKeys; import org.whispersystems.textsecuregcm.auth.CombinedUnidentifiedSenderAccessKeys;
import org.whispersystems.textsecuregcm.auth.OptionalAccess; import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices; import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices;
import org.whispersystems.textsecuregcm.entities.AccountStaleDevices; import org.whispersystems.textsecuregcm.entities.AccountStaleDevices;
@ -492,8 +493,8 @@ public class MessageController {
throw new WebApplicationException(Status.UNAUTHORIZED); throw new WebApplicationException(Status.UNAUTHORIZED);
} }
AtomicBoolean throwUnauthorized = new AtomicBoolean(false); AtomicBoolean throwUnauthorized = new AtomicBoolean(false);
byte[] empty = new byte[16]; byte[] empty = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
final Optional<byte[]> UNRESTRICTED_UNIDENTIFIED_ACCESS_KEY = Optional.of(new byte[16]); final Optional<byte[]> UNRESTRICTED_UNIDENTIFIED_ACCESS_KEY = Optional.of(new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
byte[] combinedUnknownAccessKeys = destinationAccounts.stream() byte[] combinedUnknownAccessKeys = destinationAccounts.stream()
.map(account -> { .map(account -> {
if (account.isUnrestrictedUnidentifiedAccess()) { if (account.isUnrestrictedUnidentifiedAccess()) {
@ -509,7 +510,7 @@ public class MessageController {
} }
return accessKey.get(); return accessKey.get();
}) })
.reduce(new byte[16], (bytes, bytes2) -> { .reduce(new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH], (bytes, bytes2) -> {
if (bytes.length != bytes2.length) { if (bytes.length != bytes2.length) {
throwUnauthorized.set(true); throwUnauthorized.set(true);
return bytes; return bytes;

View File

@ -11,6 +11,7 @@ import java.util.Optional;
import java.util.OptionalInt; import java.util.OptionalInt;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities; import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities;
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter; import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
import org.whispersystems.textsecuregcm.util.ExactlySize; import org.whispersystems.textsecuregcm.util.ExactlySize;
@ -34,7 +35,7 @@ public class AccountAttributes {
private String registrationLock; private String registrationLock;
@JsonProperty @JsonProperty
@ExactlySize({0, 16}) @ExactlySize({0, UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH})
private byte[] unidentifiedAccessKey; private byte[] unidentifiedAccessKey;
@JsonProperty @JsonProperty

View File

@ -35,7 +35,7 @@ class UnidentifiedAccessUtilTest {
} }
private static Stream<Arguments> checkUnidentifiedAccess() { private static Stream<Arguments> checkUnidentifiedAccess() {
final byte[] uak = new byte[16]; final byte[] uak = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(uak); new SecureRandom().nextBytes(uak);
final byte[] incorrectUak = new byte[uak.length + 1]; final byte[] incorrectUak = new byte[uak.length + 1];

View File

@ -80,6 +80,7 @@ import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess; import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicInboundMessageByteLimitConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicInboundMessageByteLimitConfiguration;
import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices; import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices;
@ -1170,7 +1171,7 @@ class MessageControllerTest {
// This looks weird, but there is a method to the madness. // This looks weird, but there is a method to the madness.
// new bytes[16] is equivalent to UNIDENTIFIED_ACCESS_BYTES ^ UNIDENTIFIED_ACCESS_BYTES // new bytes[16] is equivalent to UNIDENTIFIED_ACCESS_BYTES ^ UNIDENTIFIED_ACCESS_BYTES
// (i.e. we need to XOR all the access keys together) // (i.e. we need to XOR all the access keys together)
String accessBytes = Base64.getEncoder().encodeToString(new byte[16]); String accessBytes = Base64.getEncoder().encodeToString(new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
// start building the request // start building the request
Invocation.Builder bldr = resources Invocation.Builder bldr = resources

View File

@ -42,6 +42,7 @@ import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.ecc.Curve; import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECKeyPair; import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.entities.ECPreKey; import org.whispersystems.textsecuregcm.entities.ECPreKey;
import org.whispersystems.textsecuregcm.entities.ECSignedPreKey; import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey; import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey;
@ -79,7 +80,7 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey()); final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey());
final UUID identifier = UUID.randomUUID(); final UUID identifier = UUID.randomUUID();
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
when(targetDevice.getId()).thenReturn(Device.MASTER_ID); when(targetDevice.getId()).thenReturn(Device.MASTER_ID);
@ -142,7 +143,7 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey()); final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey());
final UUID identifier = UUID.randomUUID(); final UUID identifier = UUID.randomUUID();
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
when(targetAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey)); when(targetAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
@ -187,7 +188,7 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
void getPreKeysDeviceNotFound(final long deviceId) { void getPreKeysDeviceNotFound(final long deviceId) {
final UUID accountIdentifier = UUID.randomUUID(); final UUID accountIdentifier = UUID.randomUUID();
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final Account targetAccount = mock(Account.class); final Account targetAccount = mock(Account.class);

View File

@ -67,6 +67,7 @@ import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequest;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequestContext; import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequestContext;
import org.signal.libsignal.zkgroup.profiles.ServerZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ServerZkProfileOperations;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessChecksum; import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessChecksum;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter; import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter;
import org.whispersystems.textsecuregcm.entities.Badge; import org.whispersystems.textsecuregcm.entities.Badge;
import org.whispersystems.textsecuregcm.entities.BadgeSvg; import org.whispersystems.textsecuregcm.entities.BadgeSvg;
@ -120,7 +121,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
final UUID targetUuid = UUID.randomUUID(); final UUID targetUuid = UUID.randomUUID();
final org.whispersystems.textsecuregcm.identity.ServiceIdentifier serviceIdentifier = new AciServiceIdentifier(targetUuid); final org.whispersystems.textsecuregcm.identity.ServiceIdentifier serviceIdentifier = new AciServiceIdentifier(targetUuid);
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey()); final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey());
@ -173,7 +174,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@ParameterizedTest @ParameterizedTest
@MethodSource @MethodSource
void getUnversionedProfileUnauthenticated(final IdentityType identityType, final boolean missingUnidentifiedAccessKey, final boolean accountNotFound) { void getUnversionedProfileUnauthenticated(final IdentityType identityType, final boolean missingUnidentifiedAccessKey, final boolean accountNotFound) {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey)); when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
@ -209,7 +210,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
void getVersionedProfile(final String requestVersion, void getVersionedProfile(final String requestVersion,
@Nullable final String accountVersion, @Nullable final String accountVersion,
final boolean expectResponseHasPaymentAddress) { final boolean expectResponseHasPaymentAddress) {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final VersionedProfile profile = mock(VersionedProfile.class); final VersionedProfile profile = mock(VersionedProfile.class);
@ -268,7 +269,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@Test @Test
void getVersionedProfileVersionNotFound() { void getVersionedProfileVersionNotFound() {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey)); when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
@ -295,7 +296,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@MethodSource @MethodSource
void getVersionedProfileUnauthenticated(final boolean missingUnidentifiedAccessKey, void getVersionedProfileUnauthenticated(final boolean missingUnidentifiedAccessKey,
final boolean accountNotFound) { final boolean accountNotFound) {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false); when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false);
@ -327,7 +328,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@Test @Test
void getVersionedProfilePniInvalidArgument() { void getVersionedProfilePniInvalidArgument() {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final GetVersionedProfileAnonymousRequest request = GetVersionedProfileAnonymousRequest.newBuilder() final GetVersionedProfileAnonymousRequest request = GetVersionedProfileAnonymousRequest.newBuilder()
@ -346,7 +347,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@Test @Test
void getExpiringProfileKeyCredential() throws InvalidInputException, VerificationFailedException { void getExpiringProfileKeyCredential() throws InvalidInputException, VerificationFailedException {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final UUID targetUuid = UUID.randomUUID(); final UUID targetUuid = UUID.randomUUID();
@ -410,7 +411,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@ParameterizedTest @ParameterizedTest
@MethodSource @MethodSource
void getExpiringProfileKeyCredentialUnauthenticated(final boolean missingAccount, final boolean missingUnidentifiedAccessKey) { void getExpiringProfileKeyCredentialUnauthenticated(final boolean missingAccount, final boolean missingUnidentifiedAccessKey) {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final UUID targetUuid = UUID.randomUUID(); final UUID targetUuid = UUID.randomUUID();
@ -449,7 +450,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
@Test @Test
void getExpiringProfileKeyCredentialProfileNotFound() { void getExpiringProfileKeyCredentialProfileNotFound() {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final UUID targetUuid = UUID.randomUUID(); final UUID targetUuid = UUID.randomUUID();
@ -480,7 +481,7 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
void getExpiringProfileKeyCredentialInvalidArgument(final IdentityType identityType, final CredentialType credentialType, void getExpiringProfileKeyCredentialInvalidArgument(final IdentityType identityType, final CredentialType credentialType,
final boolean throwZkVerificationException) throws VerificationFailedException { final boolean throwZkVerificationException) throws VerificationFailedException {
final UUID targetUuid = UUID.randomUUID(); final UUID targetUuid = UUID.randomUUID();
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
if (throwZkVerificationException) { if (throwZkVerificationException) {

View File

@ -78,6 +78,7 @@ import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequest;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequestContext; import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequestContext;
import org.signal.libsignal.zkgroup.profiles.ServerZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ServerZkProfileOperations;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessChecksum; import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessChecksum;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter; import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter;
import org.whispersystems.textsecuregcm.configuration.BadgeConfiguration; import org.whispersystems.textsecuregcm.configuration.BadgeConfiguration;
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration; import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
@ -394,7 +395,7 @@ public class ProfileGrpcServiceTest extends SimpleBaseGrpcTest<ProfileGrpcServic
.setUuid(ByteString.copyFrom(UUIDUtil.toBytes(targetUuid))) .setUuid(ByteString.copyFrom(UUIDUtil.toBytes(targetUuid)))
.build()) .build())
.build(); .build();
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
new SecureRandom().nextBytes(unidentifiedAccessKey); new SecureRandom().nextBytes(unidentifiedAccessKey);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey()); final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey());

View File

@ -40,6 +40,7 @@ import org.mockito.stubbing.Answer;
import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.ecc.Curve; import org.signal.libsignal.protocol.ecc.Curve;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash; import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager; import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
@ -142,7 +143,7 @@ class AccountsManagerConcurrentModificationIntegrationTest {
final Account account = accountsManager.update( final Account account = accountsManager.update(
accountsManager.create("+14155551212", "password", null, new AccountAttributes(), new ArrayList<>()), accountsManager.create("+14155551212", "password", null, new AccountAttributes(), new ArrayList<>()),
a -> { a -> {
a.setUnidentifiedAccessKey(new byte[16]); a.setUnidentifiedAccessKey(new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
a.removeDevice(1); a.removeDevice(1);
a.addDevice(DevicesHelper.createDevice(1)); a.addDevice(DevicesHelper.createDevice(1));
}); });

View File

@ -61,6 +61,7 @@ import org.mockito.stubbing.Answer;
import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.ecc.Curve; import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECKeyPair; import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.controllers.MismatchedDevicesException; import org.whispersystems.textsecuregcm.controllers.MismatchedDevicesException;
import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.AccountAttributes;
@ -425,7 +426,7 @@ class AccountsManagerTest {
void testGetAccountByNumberNotInCache() { void testGetAccountByNumberNotInCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(null); when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(null);
when(accounts.getByE164(eq("+14152222222"))).thenReturn(Optional.of(account)); when(accounts.getByE164(eq("+14152222222"))).thenReturn(Optional.of(account));
@ -449,7 +450,7 @@ class AccountsManagerTest {
void testGetAccountByNumberNotInCacheAsync() { void testGetAccountByNumberNotInCacheAsync() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("AccountMap::+14152222222"))).thenReturn(MockRedisFuture.completedFuture(null)); when(asyncCommands.get(eq("AccountMap::+14152222222"))).thenReturn(MockRedisFuture.completedFuture(null));
when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK")); when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK"));
@ -475,7 +476,7 @@ class AccountsManagerTest {
void testGetAccountByUuidNotInCache() { void testGetAccountByUuidNotInCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("Account3::" + uuid))).thenReturn(null); when(commands.get(eq("Account3::" + uuid))).thenReturn(null);
when(accounts.getByAccountIdentifier(eq(uuid))).thenReturn(Optional.of(account)); when(accounts.getByAccountIdentifier(eq(uuid))).thenReturn(Optional.of(account));
@ -499,7 +500,7 @@ class AccountsManagerTest {
void testGetAccountByUuidNotInCacheAsync() { void testGetAccountByUuidNotInCacheAsync() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("Account3::" + uuid))).thenReturn(MockRedisFuture.completedFuture(null)); when(asyncCommands.get(eq("Account3::" + uuid))).thenReturn(MockRedisFuture.completedFuture(null));
when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK")); when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK"));
@ -526,7 +527,7 @@ class AccountsManagerTest {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("AccountMap::" + pni))).thenReturn(null); when(commands.get(eq("AccountMap::" + pni))).thenReturn(null);
when(accounts.getByPhoneNumberIdentifier(pni)).thenReturn(Optional.of(account)); when(accounts.getByPhoneNumberIdentifier(pni)).thenReturn(Optional.of(account));
@ -551,7 +552,7 @@ class AccountsManagerTest {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("AccountMap::" + pni))).thenReturn(MockRedisFuture.completedFuture(null)); when(asyncCommands.get(eq("AccountMap::" + pni))).thenReturn(MockRedisFuture.completedFuture(null));
when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK")); when(asyncCommands.setex(any(), anyLong(), any())).thenReturn(MockRedisFuture.completedFuture("OK"));
@ -577,7 +578,7 @@ class AccountsManagerTest {
void testGetAccountByUsernameHashNotInCache() { void testGetAccountByUsernameHashNotInCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account.setUsernameHash(USERNAME_HASH_1); account.setUsernameHash(USERNAME_HASH_1);
when(asyncCommands.get(eq("UAccountMap::" + BASE_64_URL_USERNAME_HASH_1))) when(asyncCommands.get(eq("UAccountMap::" + BASE_64_URL_USERNAME_HASH_1)))
@ -606,7 +607,7 @@ class AccountsManagerTest {
void testGetAccountByNumberBrokenCache() { void testGetAccountByNumberBrokenCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("AccountMap::+14152222222"))).thenThrow(new RedisException("Connection lost!")); when(commands.get(eq("AccountMap::+14152222222"))).thenThrow(new RedisException("Connection lost!"));
when(accounts.getByE164(eq("+14152222222"))).thenReturn(Optional.of(account)); when(accounts.getByE164(eq("+14152222222"))).thenReturn(Optional.of(account));
@ -630,7 +631,7 @@ class AccountsManagerTest {
void testGetAccountByNumberBrokenCacheAsync() { void testGetAccountByNumberBrokenCacheAsync() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("AccountMap::+14152222222"))) when(asyncCommands.get(eq("AccountMap::+14152222222")))
.thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost!"))); .thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost!")));
@ -658,7 +659,7 @@ class AccountsManagerTest {
void testGetAccountByUuidBrokenCache() { void testGetAccountByUuidBrokenCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("Account3::" + uuid))).thenThrow(new RedisException("Connection lost!")); when(commands.get(eq("Account3::" + uuid))).thenThrow(new RedisException("Connection lost!"));
when(accounts.getByAccountIdentifier(eq(uuid))).thenReturn(Optional.of(account)); when(accounts.getByAccountIdentifier(eq(uuid))).thenReturn(Optional.of(account));
@ -682,7 +683,7 @@ class AccountsManagerTest {
void testGetAccountByUuidBrokenCacheAsync() { void testGetAccountByUuidBrokenCacheAsync() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("Account3::" + uuid))) when(asyncCommands.get(eq("Account3::" + uuid)))
.thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost!"))); .thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost!")));
@ -712,7 +713,7 @@ class AccountsManagerTest {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("AccountMap::" + pni))).thenThrow(new RedisException("OH NO")); when(commands.get(eq("AccountMap::" + pni))).thenThrow(new RedisException("OH NO"));
when(accounts.getByPhoneNumberIdentifier(pni)).thenReturn(Optional.of(account)); when(accounts.getByPhoneNumberIdentifier(pni)).thenReturn(Optional.of(account));
@ -737,7 +738,7 @@ class AccountsManagerTest {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("AccountMap::" + pni))) when(asyncCommands.get(eq("AccountMap::" + pni)))
.thenReturn(MockRedisFuture.failedFuture(new RedisException("OH NO"))); .thenReturn(MockRedisFuture.failedFuture(new RedisException("OH NO")));
@ -766,7 +767,7 @@ class AccountsManagerTest {
void testGetAccountByUsernameBrokenCache() { void testGetAccountByUsernameBrokenCache() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account.setUsernameHash(USERNAME_HASH_1); account.setUsernameHash(USERNAME_HASH_1);
when(asyncCommands.get(eq("UAccountMap::" + BASE_64_URL_USERNAME_HASH_1))) when(asyncCommands.get(eq("UAccountMap::" + BASE_64_URL_USERNAME_HASH_1)))
@ -795,12 +796,12 @@ class AccountsManagerTest {
void testUpdate_optimisticLockingFailure() { void testUpdate_optimisticLockingFailure() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("Account3::" + uuid))).thenReturn(null); when(commands.get(eq("Account3::" + uuid))).thenReturn(null);
when(accounts.getByAccountIdentifier(uuid)).thenReturn( when(accounts.getByAccountIdentifier(uuid)).thenReturn(
Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]))); Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH])));
doThrow(ContestedOptimisticLockException.class) doThrow(ContestedOptimisticLockException.class)
.doAnswer(ACCOUNT_UPDATE_ANSWER) .doAnswer(ACCOUNT_UPDATE_ANSWER)
.when(accounts).update(any()); .when(accounts).update(any());
@ -821,12 +822,12 @@ class AccountsManagerTest {
void testUpdateAsync_optimisticLockingFailure() { void testUpdateAsync_optimisticLockingFailure() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
UUID pni = UUID.randomUUID(); UUID pni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(asyncCommands.get(eq("Account3::" + uuid))).thenReturn(null); when(asyncCommands.get(eq("Account3::" + uuid))).thenReturn(null);
when(accounts.getByAccountIdentifierAsync(uuid)).thenReturn(CompletableFuture.completedFuture( when(accounts.getByAccountIdentifierAsync(uuid)).thenReturn(CompletableFuture.completedFuture(
Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[16])))); Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, pni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]))));
when(accounts.updateAsync(any())) when(accounts.updateAsync(any()))
.thenReturn(CompletableFuture.failedFuture(new ContestedOptimisticLockException())) .thenReturn(CompletableFuture.failedFuture(new ContestedOptimisticLockException()))
@ -847,7 +848,7 @@ class AccountsManagerTest {
@Test @Test
void testUpdate_dynamoOptimisticLockingFailureDuringCreate() { void testUpdate_dynamoOptimisticLockingFailureDuringCreate() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(commands.get(eq("Account3::" + uuid))).thenReturn(null); when(commands.get(eq("Account3::" + uuid))).thenReturn(null);
when(accounts.getByAccountIdentifier(uuid)).thenReturn(Optional.empty()) when(accounts.getByAccountIdentifier(uuid)).thenReturn(Optional.empty())
@ -864,10 +865,10 @@ class AccountsManagerTest {
@Test @Test
void testUpdateDevice() { void testUpdateDevice() {
final UUID uuid = UUID.randomUUID(); final UUID uuid = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.getByAccountIdentifier(uuid)).thenReturn( when(accounts.getByAccountIdentifier(uuid)).thenReturn(
Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]))); Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH])));
assertTrue(account.getDevices().isEmpty()); assertTrue(account.getDevices().isEmpty());
@ -897,10 +898,10 @@ class AccountsManagerTest {
@Test @Test
void testUpdateDeviceAsync() { void testUpdateDeviceAsync() {
final UUID uuid = UUID.randomUUID(); final UUID uuid = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.getByAccountIdentifierAsync(uuid)).thenReturn(CompletableFuture.completedFuture( when(accounts.getByAccountIdentifierAsync(uuid)).thenReturn(CompletableFuture.completedFuture(
Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16])))); Optional.of(AccountsHelper.generateTestAccount("+14152222222", uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]))));
assertTrue(account.getDevices().isEmpty()); assertTrue(account.getDevices().isEmpty());
@ -1007,7 +1008,7 @@ class AccountsManagerTest {
@ParameterizedTest @ParameterizedTest
@MethodSource @MethodSource
void testUpdateDeviceLastSeen(final boolean expectUpdate, final long initialLastSeen, final long updatedLastSeen) { void testUpdateDeviceLastSeen(final boolean expectUpdate, final long initialLastSeen, final long updatedLastSeen) {
final Account account = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final Device device = generateTestDevice(initialLastSeen); final Device device = generateTestDevice(initialLastSeen);
account.addDevice(device); account.addDevice(device);
@ -1033,7 +1034,7 @@ class AccountsManagerTest {
final UUID uuid = UUID.randomUUID(); final UUID uuid = UUID.randomUUID();
final UUID originalPni = UUID.randomUUID(); final UUID originalPni = UUID.randomUUID();
Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account = accountsManager.changeNumber(account, targetNumber, null, null, null, null); account = accountsManager.changeNumber(account, targetNumber, null, null, null, null);
assertEquals(targetNumber, account.getNumber()); assertEquals(targetNumber, account.getNumber());
@ -1048,7 +1049,7 @@ class AccountsManagerTest {
void testChangePhoneNumberSameNumber() throws InterruptedException, MismatchedDevicesException { void testChangePhoneNumberSameNumber() throws InterruptedException, MismatchedDevicesException {
final String number = "+14152222222"; final String number = "+14152222222";
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account = accountsManager.changeNumber(account, number, null, null, null, null); account = accountsManager.changeNumber(account, number, null, null, null, null);
assertEquals(number, account.getNumber()); assertEquals(number, account.getNumber());
@ -1059,7 +1060,7 @@ class AccountsManagerTest {
void testChangePhoneNumberSameNumberWithPniData() { void testChangePhoneNumberSameNumberWithPniData() {
final String number = "+14152222222"; final String number = "+14152222222";
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair pniIdentityKeyPair = Curve.generateKeyPair(); final ECKeyPair pniIdentityKeyPair = Curve.generateKeyPair();
assertThrows(IllegalArgumentException.class, assertThrows(IllegalArgumentException.class,
() -> accountsManager.changeNumber( () -> accountsManager.changeNumber(
@ -1079,10 +1080,10 @@ class AccountsManagerTest {
final UUID originalPni = UUID.randomUUID(); final UUID originalPni = UUID.randomUUID();
final UUID targetPni = UUID.randomUUID(); final UUID targetPni = UUID.randomUUID();
final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[16]); final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount)); when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount));
Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account = accountsManager.changeNumber(account, targetNumber, null, null, null, null); account = accountsManager.changeNumber(account, targetNumber, null, null, null, null);
assertEquals(targetNumber, account.getNumber()); assertEquals(targetNumber, account.getNumber());
@ -1115,12 +1116,12 @@ class AccountsManagerTest {
2L, KeysHelper.signedKEMPreKey(4, identityKeyPair)); 2L, KeysHelper.signedKEMPreKey(4, identityKeyPair));
final Map<Long, Integer> newRegistrationIds = Map.of(1L, 201, 2L, 202); final Map<Long, Integer> newRegistrationIds = Map.of(1L, 201, 2L, 202);
final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[16]); final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount)); when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount));
when(keysManager.getPqEnabledDevices(uuid)).thenReturn(CompletableFuture.completedFuture(List.of(1L))); when(keysManager.getPqEnabledDevices(uuid)).thenReturn(CompletableFuture.completedFuture(List.of(1L)));
final List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); final List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, devices, new byte[16]); final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final Account updatedAccount = accountsManager.changeNumber( final Account updatedAccount = accountsManager.changeNumber(
account, targetNumber, new IdentityKey(Curve.generateKeyPair().getPublicKey()), newSignedKeys, newSignedPqKeys, newRegistrationIds); account, targetNumber, new IdentityKey(Curve.generateKeyPair().getPublicKey()), newSignedKeys, newSignedPqKeys, newRegistrationIds);
@ -1156,12 +1157,12 @@ class AccountsManagerTest {
1L, KeysHelper.signedKEMPreKey(3, identityKeyPair)); 1L, KeysHelper.signedKEMPreKey(3, identityKeyPair));
final Map<Long, Integer> newRegistrationIds = Map.of(1L, 201, 2L, 202); final Map<Long, Integer> newRegistrationIds = Map.of(1L, 201, 2L, 202);
final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[16]); final Account existingAccount = AccountsHelper.generateTestAccount(targetNumber, existingAccountUuid, targetPni, new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount)); when(accounts.getByE164(targetNumber)).thenReturn(Optional.of(existingAccount));
when(keysManager.getPqEnabledDevices(uuid)).thenReturn(CompletableFuture.completedFuture(List.of(1L))); when(keysManager.getPqEnabledDevices(uuid)).thenReturn(CompletableFuture.completedFuture(List.of(1L)));
final List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); final List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, devices, new byte[16]); final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, originalPni, devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
assertThrows(MismatchedDevicesException.class, assertThrows(MismatchedDevicesException.class,
() -> accountsManager.changeNumber( () -> accountsManager.changeNumber(
account, targetNumber, new IdentityKey(Curve.generateKeyPair().getPublicKey()), newSignedKeys, newSignedPqKeys, newRegistrationIds)); account, targetNumber, new IdentityKey(Curve.generateKeyPair().getPublicKey()), newSignedKeys, newSignedPqKeys, newRegistrationIds));
@ -1176,7 +1177,7 @@ class AccountsManagerTest {
final String targetNumber = "+14153333333"; final String targetNumber = "+14153333333";
final UUID uuid = UUID.randomUUID(); final UUID uuid = UUID.randomUUID();
final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount(originalNumber, uuid, UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
assertThrows(AssertionError.class, () -> accountsManager.update(account, a -> a.setNumber(targetNumber, UUID.randomUUID()))); assertThrows(AssertionError.class, () -> accountsManager.update(account, a -> a.setNumber(targetNumber, UUID.randomUUID())));
} }
@ -1186,7 +1187,7 @@ class AccountsManagerTest {
final String number = "+14152222222"; final String number = "+14152222222";
List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
Map<Long, ECSignedPreKey> newSignedKeys = Map.of( Map<Long, ECSignedPreKey> newSignedKeys = Map.of(
1L, KeysHelper.signedECPreKey(1, identityKeyPair), 1L, KeysHelper.signedECPreKey(1, identityKeyPair),
@ -1233,7 +1234,7 @@ class AccountsManagerTest {
final String number = "+14152222222"; final String number = "+14152222222";
List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final Map<Long, ECSignedPreKey> newSignedKeys = Map.of( final Map<Long, ECSignedPreKey> newSignedKeys = Map.of(
1L, KeysHelper.signedECPreKey(1, identityKeyPair), 1L, KeysHelper.signedECPreKey(1, identityKeyPair),
@ -1290,7 +1291,7 @@ class AccountsManagerTest {
final String number = "+14152222222"; final String number = "+14152222222";
List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final Map<Long, ECSignedPreKey> newSignedKeys = Map.of( final Map<Long, ECSignedPreKey> newSignedKeys = Map.of(
1L, KeysHelper.signedECPreKey(1, identityKeyPair), 1L, KeysHelper.signedECPreKey(1, identityKeyPair),
@ -1351,7 +1352,7 @@ class AccountsManagerTest {
final String number = "+14152222222"; final String number = "+14152222222";
List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final Map<Long, ECSignedPreKey> newSignedKeys = Map.of( final Map<Long, ECSignedPreKey> newSignedKeys = Map.of(
2L, KeysHelper.signedECPreKey(1, identityKeyPair), 2L, KeysHelper.signedECPreKey(1, identityKeyPair),
@ -1378,7 +1379,7 @@ class AccountsManagerTest {
final String number = "+14152222222"; final String number = "+14152222222";
List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102)); List<Device> devices = List.of(DevicesHelper.createDevice(1L, 0L, 101), DevicesHelper.createDevice(2L, 0L, 102));
Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[16]); Account account = AccountsHelper.generateTestAccount(number, UUID.randomUUID(), UUID.randomUUID(), devices, new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final ECKeyPair identityKeyPair = Curve.generateKeyPair(); final ECKeyPair identityKeyPair = Curve.generateKeyPair();
final Map<Long, ECSignedPreKey> newSignedKeys = Map.of( final Map<Long, ECSignedPreKey> newSignedKeys = Map.of(
1L, KeysHelper.signedECPreKey(1, identityKeyPair), 1L, KeysHelper.signedECPreKey(1, identityKeyPair),
@ -1404,7 +1405,7 @@ class AccountsManagerTest {
@Test @Test
void testReserveUsernameHash() throws UsernameHashNotAvailableException { void testReserveUsernameHash() throws UsernameHashNotAvailableException {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
final List<byte[]> usernameHashes = List.of(new byte[32], new byte[32]); final List<byte[]> usernameHashes = List.of(new byte[32], new byte[32]);
when(accounts.usernameHashAvailable(any())).thenReturn(CompletableFuture.completedFuture(true)); when(accounts.usernameHashAvailable(any())).thenReturn(CompletableFuture.completedFuture(true));
when(accounts.reserveUsernameHash(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(null)); when(accounts.reserveUsernameHash(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(null));
@ -1414,7 +1415,7 @@ class AccountsManagerTest {
@Test @Test
void testReserveUsernameHashNotAvailable() { void testReserveUsernameHashNotAvailable() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(accounts.usernameHashAvailable(any())).thenReturn(CompletableFuture.completedFuture(false)); when(accounts.usernameHashAvailable(any())).thenReturn(CompletableFuture.completedFuture(false));
CompletableFutureTestUtil.assertFailsWithCause(UsernameHashNotAvailableException.class, CompletableFutureTestUtil.assertFailsWithCause(UsernameHashNotAvailableException.class,
@ -1423,7 +1424,7 @@ class AccountsManagerTest {
@Test @Test
void testReserveUsernameDisabled() { void testReserveUsernameDisabled() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
when(enrollmentManager.isEnrolled(account.getUuid(), AccountsManager.USERNAME_EXPERIMENT_NAME)).thenReturn(false); when(enrollmentManager.isEnrolled(account.getUuid(), AccountsManager.USERNAME_EXPERIMENT_NAME)).thenReturn(false);
CompletableFutureTestUtil.assertFailsWithCause(UsernameHashNotAvailableException.class, CompletableFutureTestUtil.assertFailsWithCause(UsernameHashNotAvailableException.class,
accountsManager.reserveUsernameHash(account, List.of(USERNAME_HASH_1))); accountsManager.reserveUsernameHash(account, List.of(USERNAME_HASH_1)));
@ -1431,7 +1432,7 @@ class AccountsManagerTest {
@Test @Test
void testConfirmReservedUsernameHash() throws UsernameHashNotAvailableException, UsernameReservationNotFoundException { void testConfirmReservedUsernameHash() throws UsernameHashNotAvailableException, UsernameReservationNotFoundException {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
setReservationHash(account, USERNAME_HASH_1); setReservationHash(account, USERNAME_HASH_1);
when(accounts.usernameHashAvailable(Optional.of(account.getUuid()), USERNAME_HASH_1)) when(accounts.usernameHashAvailable(Optional.of(account.getUuid()), USERNAME_HASH_1))
.thenReturn(CompletableFuture.completedFuture(true)); .thenReturn(CompletableFuture.completedFuture(true));
@ -1445,7 +1446,7 @@ class AccountsManagerTest {
@Test @Test
void testConfirmReservedHashNameMismatch() { void testConfirmReservedHashNameMismatch() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
setReservationHash(account, USERNAME_HASH_1); setReservationHash(account, USERNAME_HASH_1);
when(accounts.usernameHashAvailable(eq(Optional.of(account.getUuid())), eq(USERNAME_HASH_1))) when(accounts.usernameHashAvailable(eq(Optional.of(account.getUuid())), eq(USERNAME_HASH_1)))
.thenReturn(CompletableFuture.completedFuture(true)); .thenReturn(CompletableFuture.completedFuture(true));
@ -1455,7 +1456,7 @@ class AccountsManagerTest {
@Test @Test
void testConfirmReservedLapsed() { void testConfirmReservedLapsed() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
// hash was reserved, but the reservation lapsed and another account took it // hash was reserved, but the reservation lapsed and another account took it
setReservationHash(account, USERNAME_HASH_1); setReservationHash(account, USERNAME_HASH_1);
when(accounts.usernameHashAvailable(eq(Optional.of(account.getUuid())), eq(USERNAME_HASH_1))) when(accounts.usernameHashAvailable(eq(Optional.of(account.getUuid())), eq(USERNAME_HASH_1)))
@ -1467,7 +1468,7 @@ class AccountsManagerTest {
@Test @Test
void testConfirmReservedRetry() throws UsernameHashNotAvailableException, UsernameReservationNotFoundException { void testConfirmReservedRetry() throws UsernameHashNotAvailableException, UsernameReservationNotFoundException {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account.setUsernameHash(USERNAME_HASH_1); account.setUsernameHash(USERNAME_HASH_1);
// reserved username already set, should be treated as a replay // reserved username already set, should be treated as a replay
@ -1478,7 +1479,7 @@ class AccountsManagerTest {
@Test @Test
void testConfirmReservedUsernameHashWithNoReservation() { void testConfirmReservedUsernameHashWithNoReservation() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
new ArrayList<>(), new byte[16]); new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
CompletableFutureTestUtil.assertFailsWithCause(UsernameReservationNotFoundException.class, CompletableFutureTestUtil.assertFailsWithCause(UsernameReservationNotFoundException.class,
accountsManager.confirmReservedUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1)); accountsManager.confirmReservedUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1));
verify(accounts, never()).confirmUsernameHash(any(), any(), any()); verify(accounts, never()).confirmUsernameHash(any(), any(), any());
@ -1489,7 +1490,7 @@ class AccountsManagerTest {
when(accounts.clearUsernameHash(any())) when(accounts.clearUsernameHash(any()))
.thenReturn(CompletableFuture.completedFuture(null)); .thenReturn(CompletableFuture.completedFuture(null));
Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
account.setUsernameHash(USERNAME_HASH_1); account.setUsernameHash(USERNAME_HASH_1);
accountsManager.clearUsernameHash(account).join(); accountsManager.clearUsernameHash(account).join();
verify(accounts).clearUsernameHash(eq(account)); verify(accounts).clearUsernameHash(eq(account));
@ -1497,7 +1498,7 @@ class AccountsManagerTest {
@Test @Test
void testSetUsernameViaUpdate() { void testSetUsernameViaUpdate() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[16]); final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
assertThrows(AssertionError.class, () -> accountsManager.update(account, a -> a.setUsernameHash(USERNAME_HASH_1))); assertThrows(AssertionError.class, () -> accountsManager.update(account, a -> a.setUsernameHash(USERNAME_HASH_1)));
} }

View File

@ -47,6 +47,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessUtil;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.identity.IdentityType; import org.whispersystems.textsecuregcm.identity.IdentityType;
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables; import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
@ -1032,7 +1033,7 @@ class AccountsTest {
} }
private static Account generateAccount(String number, UUID uuid, final UUID pni, List<Device> devices) { private static Account generateAccount(String number, UUID uuid, final UUID pni, List<Device> devices) {
final byte[] unidentifiedAccessKey = new byte[16]; final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
final Random random = new Random(System.currentTimeMillis()); final Random random = new Random(System.currentTimeMillis());
Arrays.fill(unidentifiedAccessKey, (byte) random.nextInt(255)); Arrays.fill(unidentifiedAccessKey, (byte) random.nextInt(255));