Handle edge cases of Math.abs on integers.
This commit is contained in:
parent
2c2c497c12
commit
d138fa45df
|
@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.auth;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.signal.libsignal.protocol.kdf.HKDF;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
|
@ -32,13 +33,13 @@ public class AuthenticationCredentials {
|
|||
}
|
||||
|
||||
public AuthenticationCredentials(String authenticationToken) {
|
||||
this.salt = String.valueOf(Math.abs(new SecureRandom().nextInt()));
|
||||
this.salt = String.valueOf(Util.ensureNonNegativeInt(new SecureRandom().nextInt()));
|
||||
this.hashedAuthenticationToken = getV2HashedValue(salt, authenticationToken);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public AuthenticationCredentials v1ForTesting(String authenticationToken) {
|
||||
String salt = String.valueOf(Math.abs(new SecureRandom().nextInt()));
|
||||
String salt = String.valueOf(Util.ensureNonNegativeInt(new SecureRandom().nextInt()));
|
||||
return new AuthenticationCredentials(getV1HashedValue(salt, authenticationToken), salt);
|
||||
}
|
||||
|
||||
|
|
|
@ -146,9 +146,18 @@ public class BaseAccountAuthenticator {
|
|||
|
||||
@VisibleForTesting
|
||||
public Account updateLastSeen(Account account, Device device) {
|
||||
final long lastSeenOffsetSeconds = Math.abs(account.getUuid().getLeastSignificantBits()) % ChronoUnit.DAYS.getDuration().toSeconds();
|
||||
// compute a non-negative integer between 0 and 86400.
|
||||
long n = Util.ensureNonNegativeLong(account.getUuid().getLeastSignificantBits());
|
||||
final long lastSeenOffsetSeconds = n % ChronoUnit.DAYS.getDuration().toSeconds();
|
||||
|
||||
// produce a truncated timestamp which is either today at UTC midnight
|
||||
// or yesterday at UTC midnight, based on per-user randomized offset used.
|
||||
final long todayInMillisWithOffset = Util.todayInMillisGivenOffsetFromNow(clock, Duration.ofSeconds(lastSeenOffsetSeconds).negated());
|
||||
|
||||
// only update the device's last seen time when it falls behind the truncated timestamp.
|
||||
// this ensure a few things:
|
||||
// (1) each account will only update last-seen at most once per day
|
||||
// (2) these updates will occur throughout the day rather than all occurring at UTC midnight.
|
||||
if (device.getLastSeen() < todayInMillisWithOffset) {
|
||||
Metrics.summary(DAYS_SINCE_LAST_SEEN_DISTRIBUTION_NAME, IS_PRIMARY_DEVICE_TAG, String.valueOf(device.isMaster()))
|
||||
.record(Duration.ofMillis(todayInMillisWithOffset - device.getLastSeen()).toDays());
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfigurati
|
|||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicTurnConfiguration;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.util.Pair;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
import org.whispersystems.textsecuregcm.util.WeightedRandomSelect;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
|
@ -36,7 +37,7 @@ public class TurnTokenGenerator {
|
|||
List<String> urls = urls(e164);
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
long validUntilSeconds = (System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)) / 1000;
|
||||
long user = Math.abs(new SecureRandom().nextInt());
|
||||
long user = Util.ensureNonNegativeInt(new SecureRandom().nextInt());
|
||||
String userTime = validUntilSeconds + ":" + user;
|
||||
|
||||
mac.init(new SecretKeySpec(key, "HmacSHA1"));
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.whispersystems.textsecuregcm.entities.UserRemoteConfigList;
|
|||
import org.whispersystems.textsecuregcm.storage.RemoteConfig;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfigsManager;
|
||||
import org.whispersystems.textsecuregcm.util.Conversions;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
@Path("/v1/config")
|
||||
public class RemoteConfigController {
|
||||
|
@ -133,7 +134,7 @@ public class RemoteConfigController {
|
|||
digest.update(bb.array());
|
||||
|
||||
byte[] hash = digest.digest(hashKey);
|
||||
int bucket = (int)(Math.abs(Conversions.byteArrayToLong(hash)) % 100);
|
||||
int bucket = (int)(Util.ensureNonNegativeLong(Conversions.byteArrayToLong(hash)) % 100);
|
||||
|
||||
return bucket < configPercentage;
|
||||
}
|
||||
|
|
|
@ -191,4 +191,29 @@ public class Util {
|
|||
public static Optional<String> findBestLocale(List<LanguageRange> priorityList, Collection<String> supportedLocales) {
|
||||
return Optional.ofNullable(Locale.lookupTag(priorityList, supportedLocales));
|
||||
}
|
||||
|
||||
/**
|
||||
* Map ints to non-negative ints.
|
||||
* <br>
|
||||
* Unlike Math.abs this method handles Integer.MIN_VALUE correctly.
|
||||
*
|
||||
* @param n any int value
|
||||
* @return an int value guaranteed to be non-negative
|
||||
*/
|
||||
public static int ensureNonNegativeInt(int n) {
|
||||
return n == Integer.MIN_VALUE ? 0 : Math.abs(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map longs to non-negative longs.
|
||||
* <br>
|
||||
* Unlike Math.abs this method handles Long.MIN_VALUE correctly.
|
||||
*
|
||||
* @param n any long value
|
||||
* @return a long value guaranteed to be non-negative
|
||||
*/
|
||||
public static long ensureNonNegativeLong(long n) {
|
||||
return n == Long.MIN_VALUE ? 0 : Math.abs(n);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue