From 358a2865230536814a43443397313e715a19d5d0 Mon Sep 17 00:00:00 2001 From: Chris Eager <79161849+eager-signal@users.noreply.github.com> Date: Mon, 6 Feb 2023 12:16:59 -0600 Subject: [PATCH] Use `java.util` Hex and Base64 codecs --- pom.xml | 6 -- service/pom.xml | 4 - .../textsecuregcm/auth/SaltedTokenHash.java | 10 +- .../ArtServiceConfiguration.java | 12 +-- .../DirectoryClientConfiguration.java | 11 +-- .../PaymentsServiceConfiguration.java | 12 +-- .../SecureBackupServiceConfiguration.java | 11 +-- .../SecureStorageServiceConfiguration.java | 7 +- .../controllers/AccountController.java | 4 +- .../controllers/ArtController.java | 17 ++-- .../controllers/DirectoryController.java | 4 +- .../controllers/PaymentsController.java | 11 +-- .../controllers/ProfileController.java | 18 ++-- .../controllers/SecureBackupController.java | 15 +-- .../controllers/SecureStorageController.java | 13 +-- .../SecureValueRecovery2Controller.java | 4 +- .../controllers/StickerController.java | 4 +- .../gcp/CanonicalRequestSigner.java | 6 +- .../limits/PushChallengeManager.java | 9 +- .../textsecuregcm/redis/ClusterLuaScript.java | 4 +- .../textsecuregcm/s3/PostPolicyGenerator.java | 47 ++++----- .../subscriptions/BraintreeManager.java | 4 +- .../subscriptions/StripeManager.java | 4 +- .../textsecuregcm/util/Hex.java | 98 ------------------- .../controllers/AccountControllerTest.java | 15 +-- .../controllers/ProfileControllerTest.java | 14 ++- .../storage/ChangeNumberManagerTest.java | 4 +- 27 files changed, 118 insertions(+), 250 deletions(-) delete mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/util/Hex.java diff --git a/pom.xml b/pom.xml index 2aa2c53c2..b2a0bd118 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,6 @@ 1.12.376 2.19.8 3.19.0 - 1.15 1.9.0 2.9.0 2.0.34 @@ -187,11 +186,6 @@ semver4j ${semver4j.version} - - commons-codec - commons-codec - ${commons-codec.version} - commons-io commons-io diff --git a/service/pom.xml b/service/pom.xml index dc6c0067a..cf95b07b1 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -173,10 +173,6 @@ org.apache.commons commons-lang3 - - commons-codec - commons-codec - org.apache.commons commons-csv diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/SaltedTokenHash.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/SaltedTokenHash.java index c97d78451..8cfecfe7f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/SaltedTokenHash.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/SaltedTokenHash.java @@ -8,7 +8,7 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import org.apache.commons.codec.binary.Hex; +import java.util.HexFormat; import org.signal.libsignal.protocol.kdf.HKDF; public record SaltedTokenHash(String hash, String salt) { @@ -52,13 +52,13 @@ public record SaltedTokenHash(String hash, String salt) { private static String generateSalt() { final byte[] salt = new byte[SALT_SIZE]; SECURE_RANDOM.nextBytes(salt); - return Hex.encodeHexString(salt); + return HexFormat.of().formatHex(salt); } private static String calculateV1Hash(final String salt, final String token) { try { - return new String( - Hex.encodeHex(MessageDigest.getInstance("SHA1").digest((salt + token).getBytes(StandardCharsets.UTF_8)))); + return HexFormat.of() + .formatHex(MessageDigest.getInstance("SHA1").digest((salt + token).getBytes(StandardCharsets.UTF_8))); } catch (final NoSuchAlgorithmException e) { throw new AssertionError(e); } @@ -70,6 +70,6 @@ public record SaltedTokenHash(String hash, String salt) { salt.getBytes(StandardCharsets.UTF_8), // salt AUTH_TOKEN_HKDF_INFO, 32); - return V2_PREFIX + Hex.encodeHexString(secret); + return V2_PREFIX + HexFormat.of().formatHex(secret); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java index d14cbda86..f0cea1d9f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java @@ -6,10 +6,8 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; - import java.time.Duration; +import java.util.HexFormat; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -27,12 +25,12 @@ public class ArtServiceConfiguration { @NotNull private Duration tokenExpiration = Duration.ofDays(1); - public byte[] getUserAuthenticationTokenSharedSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenSharedSecret.toCharArray()); + public byte[] getUserAuthenticationTokenSharedSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenSharedSecret); } - public byte[] getUserAuthenticationTokenUserIdSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenUserIdSecret.toCharArray()); + public byte[] getUserAuthenticationTokenUserIdSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenUserIdSecret); } public Duration getTokenExpiration() { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/DirectoryClientConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/DirectoryClientConfiguration.java index 6550ff414..d612a4b07 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/DirectoryClientConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/DirectoryClientConfiguration.java @@ -5,9 +5,8 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.HexFormat; import javax.validation.constraints.NotEmpty; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; public class DirectoryClientConfiguration { @@ -19,12 +18,12 @@ public class DirectoryClientConfiguration { @JsonProperty private String userAuthenticationTokenUserIdSecret; - public byte[] getUserAuthenticationTokenSharedSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenSharedSecret.toCharArray()); + public byte[] getUserAuthenticationTokenSharedSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenSharedSecret); } - public byte[] getUserAuthenticationTokenUserIdSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenUserIdSecret.toCharArray()); + public byte[] getUserAuthenticationTokenUserIdSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenUserIdSecret); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/PaymentsServiceConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/PaymentsServiceConfiguration.java index 1dfd63b86..474474a0f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/PaymentsServiceConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/PaymentsServiceConfiguration.java @@ -6,13 +6,11 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; +import java.util.HexFormat; import java.util.List; import java.util.Map; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; public class PaymentsServiceConfiguration { @@ -36,8 +34,8 @@ public class PaymentsServiceConfiguration { @JsonProperty private List paymentCurrencies; - public byte[] getUserAuthenticationTokenSharedSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenSharedSecret.toCharArray()); + public byte[] getUserAuthenticationTokenSharedSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenSharedSecret); } public String getCoinMarketCapApiKey() { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureBackupServiceConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureBackupServiceConfiguration.java index cbeb4c0d4..020172c5a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureBackupServiceConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureBackupServiceConfiguration.java @@ -6,14 +6,13 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.annotations.VisibleForTesting; +import java.util.HexFormat; +import java.util.List; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; -import java.util.List; public class SecureBackupServiceConfiguration { @@ -39,8 +38,8 @@ public class SecureBackupServiceConfiguration { @JsonProperty private RetryConfiguration retry = new RetryConfiguration(); - public byte[] getUserAuthenticationTokenSharedSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenSharedSecret.toCharArray()); + public byte[] getUserAuthenticationTokenSharedSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenSharedSecret); } @VisibleForTesting diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureStorageServiceConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureStorageServiceConfiguration.java index 9fb4e6bfc..4c9bf35aa 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureStorageServiceConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/SecureStorageServiceConfiguration.java @@ -5,12 +5,11 @@ package org.whispersystems.textsecuregcm.configuration; +import java.util.HexFormat; import java.util.List; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; public record SecureStorageServiceConfiguration(@NotEmpty String userAuthenticationTokenSharedSecret, @NotBlank String uri, @@ -27,7 +26,7 @@ public record SecureStorageServiceConfiguration(@NotEmpty String userAuthenticat } } - public byte[] decodeUserAuthenticationTokenSharedSecret() throws DecoderException { - return Hex.decodeHex(userAuthenticationTokenSharedSecret.toCharArray()); + public byte[] decodeUserAuthenticationTokenSharedSecret() { + return HexFormat.of().parseHex(userAuthenticationTokenSharedSecret); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index e957bf4b2..63eb99dab 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -27,6 +27,7 @@ import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.Base64; +import java.util.HexFormat; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -108,7 +109,6 @@ import org.whispersystems.textsecuregcm.storage.UsernameHashNotAvailableExceptio import org.whispersystems.textsecuregcm.storage.UsernameReservationNotFoundException; import org.whispersystems.textsecuregcm.util.Constants; import org.whispersystems.textsecuregcm.util.HeaderUtils; -import org.whispersystems.textsecuregcm.util.Hex; import org.whispersystems.textsecuregcm.util.ImpossiblePhoneNumberException; import org.whispersystems.textsecuregcm.util.NonNormalizedPhoneNumberException; import org.whispersystems.textsecuregcm.util.Optionals; @@ -947,7 +947,7 @@ public class AccountController { byte[] challenge = new byte[16]; random.nextBytes(challenge); - return Hex.toStringCondensed(challenge); + return HexFormat.of().formatHex(challenge); } private byte[] createRegistrationSession(final Phonenumber.PhoneNumber phoneNumber) throws RateLimitExceededException { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java index 031998367..47fb1f2a3 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java @@ -12,7 +12,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.commons.codec.DecoderException; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; @@ -25,16 +24,12 @@ public class ArtController { private final RateLimiters rateLimiters; public static ExternalServiceCredentialsGenerator credentialsGenerator(final ArtServiceConfiguration cfg) { - try { - return ExternalServiceCredentialsGenerator - .builder(cfg.getUserAuthenticationTokenSharedSecret()) - .withUserDerivationKey(cfg.getUserAuthenticationTokenUserIdSecret()) - .prependUsername(false) - .truncateSignature(false) - .build(); - } catch (DecoderException e) { - throw new IllegalArgumentException(e); - } + return ExternalServiceCredentialsGenerator + .builder(cfg.getUserAuthenticationTokenSharedSecret()) + .withUserDerivationKey(cfg.getUserAuthenticationTokenUserIdSecret()) + .prependUsername(false) + .truncateSignature(false) + .build(); } public ArtController(RateLimiters rateLimiters, diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DirectoryController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DirectoryController.java index 0c2801b0b..ff6c2441e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DirectoryController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DirectoryController.java @@ -13,7 +13,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.apache.commons.codec.DecoderException; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; import org.whispersystems.textsecuregcm.configuration.DirectoryClientConfiguration; @@ -23,8 +22,7 @@ public class DirectoryController { private final ExternalServiceCredentialsGenerator directoryServiceTokenGenerator; - public static ExternalServiceCredentialsGenerator credentialsGenerator(final DirectoryClientConfiguration cfg) - throws DecoderException { + public static ExternalServiceCredentialsGenerator credentialsGenerator(final DirectoryClientConfiguration cfg) { return ExternalServiceCredentialsGenerator .builder(cfg.getUserAuthenticationTokenSharedSecret()) .withUserDerivationKey(cfg.getUserAuthenticationTokenUserIdSecret()) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/PaymentsController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/PaymentsController.java index 0e0ea530b..ed13445d7 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/PaymentsController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/PaymentsController.java @@ -11,7 +11,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.commons.codec.DecoderException; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; @@ -25,17 +24,17 @@ public class PaymentsController { private final ExternalServiceCredentialsGenerator paymentsServiceCredentialsGenerator; private final CurrencyConversionManager currencyManager; - - public static ExternalServiceCredentialsGenerator credentialsGenerator(final PaymentsServiceConfiguration cfg) - throws DecoderException { + + public static ExternalServiceCredentialsGenerator credentialsGenerator(final PaymentsServiceConfiguration cfg) { return ExternalServiceCredentialsGenerator .builder(cfg.getUserAuthenticationTokenSharedSecret()) .prependUsername(true) .build(); } - public PaymentsController(final CurrencyConversionManager currencyManager, final ExternalServiceCredentialsGenerator paymentsServiceCredentialsGenerator) { - this.currencyManager = currencyManager; + public PaymentsController(final CurrencyConversionManager currencyManager, + final ExternalServiceCredentialsGenerator paymentsServiceCredentialsGenerator) { + this.currencyManager = currencyManager; this.paymentsServiceCredentialsGenerator = paymentsServiceCredentialsGenerator; } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java index 32fcbc8c8..1e5ffe9e3 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.Collections; +import java.util.HexFormat; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; @@ -64,8 +65,6 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.StringUtils; import org.signal.libsignal.zkgroup.InvalidInputException; import org.signal.libsignal.zkgroup.VerificationFailedException; @@ -530,10 +529,11 @@ public class ProfileController { final UUID uuid) { try { final ProfileKeyCommitment commitment = new ProfileKeyCommitment(profile.getCommitment()); - final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest(Hex.decodeHex(encodedProfileCredentialRequest)); + final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest( + HexFormat.of().parseHex(encodedProfileCredentialRequest)); return zkProfileOperations.issueProfileKeyCredential(request, uuid, commitment); - } catch (DecoderException | VerificationFailedException | InvalidInputException e) { + } catch (IllegalArgumentException | VerificationFailedException | InvalidInputException e) { throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).build()); } } @@ -545,10 +545,11 @@ public class ProfileController { try { final ProfileKeyCommitment commitment = new ProfileKeyCommitment(profile.getCommitment()); - final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest(Hex.decodeHex(encodedCredentialRequest)); + final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest( + HexFormat.of().parseHex(encodedCredentialRequest)); return zkProfileOperations.issuePniCredential(request, accountIdentifier, phoneNumberIdentifier, commitment); - } catch (DecoderException | VerificationFailedException | InvalidInputException e) { + } catch (IllegalArgumentException | VerificationFailedException | InvalidInputException e) { throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).build()); } } @@ -561,10 +562,11 @@ public class ProfileController { try { final ProfileKeyCommitment commitment = new ProfileKeyCommitment(profile.getCommitment()); - final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest(Hex.decodeHex(encodedCredentialRequest)); + final ProfileKeyCredentialRequest request = new ProfileKeyCredentialRequest( + HexFormat.of().parseHex(encodedCredentialRequest)); return zkProfileOperations.issueExpiringProfileKeyCredential(request, accountIdentifier, commitment, expiration); - } catch (DecoderException | VerificationFailedException | InvalidInputException e) { + } catch (IllegalArgumentException | VerificationFailedException | InvalidInputException e) { throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).build()); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureBackupController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureBackupController.java index 863f20ab7..740e89514 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureBackupController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureBackupController.java @@ -24,7 +24,6 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.commons.codec.DecoderException; import org.apache.commons.lang3.tuple.Pair; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; @@ -53,15 +52,11 @@ public class SecureBackupController { public static ExternalServiceCredentialsGenerator credentialsGenerator( final SecureBackupServiceConfiguration cfg, final Clock clock) { - try { - return ExternalServiceCredentialsGenerator - .builder(cfg.getUserAuthenticationTokenSharedSecret()) - .prependUsername(true) - .withClock(clock) - .build(); - } catch (final DecoderException e) { - throw new IllegalStateException(e); - } + return ExternalServiceCredentialsGenerator + .builder(cfg.getUserAuthenticationTokenSharedSecret()) + .prependUsername(true) + .withClock(clock) + .build(); } public SecureBackupController( diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureStorageController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureStorageController.java index b83a93e5a..acbc0b024 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureStorageController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureStorageController.java @@ -11,7 +11,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.commons.codec.DecoderException; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; @@ -23,14 +22,10 @@ public class SecureStorageController { private final ExternalServiceCredentialsGenerator storageServiceCredentialsGenerator; public static ExternalServiceCredentialsGenerator credentialsGenerator(final SecureStorageServiceConfiguration cfg) { - try { - return ExternalServiceCredentialsGenerator - .builder(cfg.decodeUserAuthenticationTokenSharedSecret()) - .prependUsername(true) - .build(); - } catch (DecoderException e) { - throw new IllegalArgumentException(e); - } + return ExternalServiceCredentialsGenerator + .builder(cfg.decodeUserAuthenticationTokenSharedSecret()) + .prependUsername(true) + .build(); } public SecureStorageController(ExternalServiceCredentialsGenerator storageServiceCredentialsGenerator) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureValueRecovery2Controller.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureValueRecovery2Controller.java index 7f785f56b..f0e181c9c 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureValueRecovery2Controller.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SecureValueRecovery2Controller.java @@ -11,7 +11,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.commons.codec.DecoderException; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; @@ -20,8 +19,7 @@ import org.whispersystems.textsecuregcm.configuration.SecureValueRecovery2Config @Path("/v2/backup") public class SecureValueRecovery2Controller { - public static ExternalServiceCredentialsGenerator credentialsGenerator(final SecureValueRecovery2Configuration cfg) - throws DecoderException { + public static ExternalServiceCredentialsGenerator credentialsGenerator(final SecureValueRecovery2Configuration cfg) { return ExternalServiceCredentialsGenerator .builder(cfg.userAuthenticationTokenSharedSecret()) .withUserDerivationKey(cfg.userIdTokenSharedSecret()) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/StickerController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/StickerController.java index 3f8bd0ae5..4b53ecbbf 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/StickerController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/StickerController.java @@ -9,6 +9,7 @@ import io.dropwizard.auth.Auth; import java.security.SecureRandom; import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.util.HexFormat; import java.util.LinkedList; import java.util.List; import javax.validation.constraints.Max; @@ -25,7 +26,6 @@ import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.s3.PolicySigner; import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator; import org.whispersystems.textsecuregcm.util.Constants; -import org.whispersystems.textsecuregcm.util.Hex; import org.whispersystems.textsecuregcm.util.Pair; @Path("/v1/sticker") @@ -78,7 +78,7 @@ public class StickerController { byte[] object = new byte[16]; new SecureRandom().nextBytes(object); - return Hex.toStringCondensed(object); + return HexFormat.of().formatHex(object); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/gcp/CanonicalRequestSigner.java b/service/src/main/java/org/whispersystems/textsecuregcm/gcp/CanonicalRequestSigner.java index 72e1fabf2..331336d41 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/gcp/CanonicalRequestSigner.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/gcp/CanonicalRequestSigner.java @@ -17,10 +17,10 @@ import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; +import java.util.HexFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nonnull; -import org.apache.commons.codec.binary.Hex; public class CanonicalRequestSigner { @@ -52,7 +52,7 @@ public class CanonicalRequestSigner { throw new AssertionError(e); } sha256.update(canonicalRequest.getCanonicalRequest().getBytes(StandardCharsets.UTF_8)); - result.append(Hex.encodeHex(sha256.digest())); + result.append(HexFormat.of().formatHex(sha256.digest())); return result.toString(); } @@ -67,7 +67,7 @@ public class CanonicalRequestSigner { } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { throw new AssertionError(e); } - return Hex.encodeHexString(signature); + return HexFormat.of().formatHex(signature); } private static PrivateKey initializeRsaSigningKey(String rsaSigningKey) throws IOException, InvalidKeyException, InvalidKeySpecException { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/limits/PushChallengeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/limits/PushChallengeManager.java index 0c43610ae..4ec20570d 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/limits/PushChallengeManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/limits/PushChallengeManager.java @@ -10,8 +10,7 @@ import static com.codahale.metrics.MetricRegistry.name; import io.micrometer.core.instrument.Metrics; import java.security.SecureRandom; import java.time.Duration; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; +import java.util.HexFormat; import org.apache.commons.lang3.StringUtils; import org.whispersystems.textsecuregcm.push.NotPushRegisteredException; import org.whispersystems.textsecuregcm.push.PushNotificationManager; @@ -55,7 +54,7 @@ public class PushChallengeManager { final String platform; if (pushChallengeDynamoDb.add(account.getUuid(), token, CHALLENGE_TTL)) { - pushNotificationManager.sendRateLimitChallengeNotification(account, Hex.encodeHexString(token)); + pushNotificationManager.sendRateLimitChallengeNotification(account, HexFormat.of().formatHex(token)); sent = true; @@ -83,8 +82,8 @@ public class PushChallengeManager { boolean success = false; try { - success = pushChallengeDynamoDb.remove(account.getUuid(), Hex.decodeHex(challengeTokenHex)); - } catch (final DecoderException ignored) { + success = pushChallengeDynamoDb.remove(account.getUuid(), HexFormat.of().parseHex(challengeTokenHex)); + } catch (final IllegalArgumentException ignored) { } final String platform = account.getMasterDevice().map(masterDevice -> { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java b/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java index 3b3e70898..3915f53bd 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java @@ -15,9 +15,9 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.HexFormat; import java.util.List; import java.util.concurrent.CompletableFuture; -import org.apache.commons.codec.binary.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; @@ -60,7 +60,7 @@ public class ClusterLuaScript { this.script = script; try { - this.sha = Hex.encodeHexString(MessageDigest.getInstance("SHA-1").digest(script.getBytes(StandardCharsets.UTF_8))); + this.sha = HexFormat.of().formatHex(MessageDigest.getInstance("SHA-1").digest(script.getBytes(StandardCharsets.UTF_8))); } catch (final NoSuchAlgorithmException e) { // All Java implementations are required to support SHA-1, so this should never happen throw new AssertionError(e); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/s3/PostPolicyGenerator.java b/service/src/main/java/org/whispersystems/textsecuregcm/s3/PostPolicyGenerator.java index fa7767a2d..744891e8e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/s3/PostPolicyGenerator.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/s3/PostPolicyGenerator.java @@ -5,12 +5,11 @@ package org.whispersystems.textsecuregcm.s3; -import org.apache.commons.codec.binary.Base64; -import org.whispersystems.textsecuregcm.util.Pair; - -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.util.Base64; +import org.whispersystems.textsecuregcm.util.Pair; public class PostPolicyGenerator { @@ -28,30 +27,26 @@ public class PostPolicyGenerator { } public Pair createFor(ZonedDateTime now, String object, int maxSizeInBytes) { - try { - String expiration = now.plusMinutes(30).format(DateTimeFormatter.ISO_INSTANT); - String credentialDate = now.format(CREDENTIAL_DATE); - String requestDate = now.format(AWS_DATE_TIME ); - String credential = String.format("%s/%s/%s/s3/aws4_request", awsAccessId, credentialDate, region); + String expiration = now.plusMinutes(30).format(DateTimeFormatter.ISO_INSTANT); + String credentialDate = now.format(CREDENTIAL_DATE); + String requestDate = now.format(AWS_DATE_TIME); + String credential = String.format("%s/%s/%s/s3/aws4_request", awsAccessId, credentialDate, region); - String policy = String.format("{ \"expiration\": \"%s\",\n" + - " \"conditions\": [\n" + - " {\"bucket\": \"%s\"},\n" + - " {\"key\": \"%s\"},\n" + - " {\"acl\": \"private\"},\n" + - " [\"starts-with\", \"$Content-Type\", \"\"],\n" + - " [\"content-length-range\", 1, " + maxSizeInBytes + "],\n" + - "\n" + - " {\"x-amz-credential\": \"%s\"},\n" + - " {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"},\n" + - " {\"x-amz-date\": \"%s\" }\n" + - " ]\n" + - "}", expiration, bucket, object, credential, requestDate); + String policy = String.format("{ \"expiration\": \"%s\",\n" + + " \"conditions\": [\n" + + " {\"bucket\": \"%s\"},\n" + + " {\"key\": \"%s\"},\n" + + " {\"acl\": \"private\"},\n" + + " [\"starts-with\", \"$Content-Type\", \"\"],\n" + + " [\"content-length-range\", 1, " + maxSizeInBytes + "],\n" + + "\n" + + " {\"x-amz-credential\": \"%s\"},\n" + + " {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"},\n" + + " {\"x-amz-date\": \"%s\" }\n" + + " ]\n" + + "}", expiration, bucket, object, credential, requestDate); - return new Pair<>(credential, Base64.encodeBase64String(policy.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } + return new Pair<>(credential, Base64.getEncoder().encodeToString(policy.getBytes(StandardCharsets.UTF_8))); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java index 939534eca..1ba3738a2 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.math.BigDecimal; import java.time.Instant; import java.util.Comparator; +import java.util.HexFormat; import java.util.List; import java.util.Locale; import java.util.Map; @@ -35,7 +36,6 @@ import javax.annotation.Nullable; import javax.ws.rs.ClientErrorException; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; -import org.apache.commons.codec.binary.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; @@ -233,7 +233,7 @@ public class BraintreeManager implements SubscriptionProcessorManager { public CompletableFuture createCustomer(final byte[] subscriberUser) { return CompletableFuture.supplyAsync(() -> { final CustomerRequest request = new CustomerRequest() - .customField("subscriber_user", Hex.encodeHexString(subscriberUser)); + .customField("subscriber_user", HexFormat.of().formatHex(subscriberUser)); try { return braintreeGateway.customer().create(request); } catch (BraintreeException e) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java index 607f0ec78..d5f313206 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java @@ -44,6 +44,7 @@ import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HexFormat; import java.util.List; import java.util.Locale; import java.util.Map; @@ -61,7 +62,6 @@ import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.StringUtils; import org.whispersystems.textsecuregcm.util.Conversions; @@ -124,7 +124,7 @@ public class StripeManager implements SubscriptionProcessorManager { public CompletableFuture createCustomer(byte[] subscriberUser) { return CompletableFuture.supplyAsync(() -> { CustomerCreateParams params = CustomerCreateParams.builder() - .putMetadata("subscriberUser", Hex.encodeHexString(subscriberUser)) + .putMetadata("subscriberUser", HexFormat.of().formatHex(subscriberUser)) .build(); try { return Customer.create(params, commonOptions(generateIdempotencyKeyForSubscriberUser(subscriberUser))); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/Hex.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/Hex.java deleted file mode 100644 index 04a555d12..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/Hex.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ -package org.whispersystems.textsecuregcm.util; - -/** - * Utility for generating hex dumps a la hexl-mode in emacs. - */ -public class Hex { - - final static String EOL = System.getProperty("line.separator"); - - private final static char[] HEX_DIGITS = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' - }; - - public static String toString(byte[] bytes) { - return toString(bytes, 0, bytes.length, false); - } - - public static String toStringCondensed(byte[] bytes) { - return toString(bytes, 0, bytes.length, true); - } - - public static String toString(byte[] bytes, int offset, int length, boolean condensed) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < length; i++) { - appendHexChar(buf, bytes[offset + i]); - if (!condensed) buf.append(' '); - } - return buf.toString(); - } - - public static String dump(byte[] bytes) { - return dump(bytes, 0, bytes.length); - } - - public static String dump(byte[] bytes, int offset, int length) { - StringBuffer buf = new StringBuffer(); - int lines = ((length - 1) / 16) + 1; - int lineOffset; - int lineLength; - - for (int i = 0; i < lines; i++) { - lineOffset = (i * 16) + offset; - lineLength = Math.min(16, (length - (i * 16))); - appendDumpLine(buf, i, bytes, lineOffset, lineLength); - buf.append(EOL); - } - - return buf.toString(); - } - - private static void appendDumpLine(StringBuffer buf, int line, - byte[] bytes, int lineOffset, - int lineLength) - { - buf.append(HEX_DIGITS[(line >> 28) & 0xf]); - buf.append(HEX_DIGITS[(line >> 24) & 0xf]); - buf.append(HEX_DIGITS[(line >> 20) & 0xf]); - buf.append(HEX_DIGITS[(line >> 16) & 0xf]); - buf.append(HEX_DIGITS[(line >> 12) & 0xf]); - buf.append(HEX_DIGITS[(line >> 8) & 0xf]); - buf.append(HEX_DIGITS[(line >> 4) & 0xf]); - buf.append(HEX_DIGITS[(line ) & 0xf]); - buf.append(": "); - - for (int i = 0; i < 16; i++) { - int idx = i + lineOffset; - if (i < lineLength) { - int b = bytes[idx]; - appendHexChar(buf, b); - } else { - buf.append(" "); - } - if ((i % 2) == 1) { - buf.append(' '); - } - } - - for (int i = 0; i < 16 && i < lineLength; i++) { - int idx = i + lineOffset; - int b = bytes[idx]; - if (b >= 0x20 && b <= 0x7e) { - buf.append((char)b); - } else { - buf.append('.'); - } - } - } - - private static void appendHexChar(StringBuffer buf, int b) { - buf.append(HEX_DIGITS[(b >> 4) & 0xf]); - buf.append(HEX_DIGITS[b & 0xf]); - } - -} diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java index 83f439628..25fafea9b 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java @@ -38,6 +38,7 @@ import java.time.Duration; import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.Optional; @@ -114,7 +115,6 @@ import org.whispersystems.textsecuregcm.storage.UsernameHashNotAvailableExceptio import org.whispersystems.textsecuregcm.storage.UsernameReservationNotFoundException; import org.whispersystems.textsecuregcm.tests.util.AccountsHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; -import org.whispersystems.textsecuregcm.util.Hex; import org.whispersystems.textsecuregcm.util.MockUtils; import org.whispersystems.textsecuregcm.util.SystemMapper; import org.whispersystems.textsecuregcm.util.TestClock; @@ -226,7 +226,8 @@ class AccountControllerTest { clearInvocations(AuthHelper.VALID_ACCOUNT, AuthHelper.UNDISCOVERABLE_ACCOUNT); new SecureRandom().nextBytes(registration_lock_key); - SaltedTokenHash registrationLockCredentials = SaltedTokenHash.generateFor(Hex.toStringCondensed(registration_lock_key)); + SaltedTokenHash registrationLockCredentials = SaltedTokenHash.generateFor( + HexFormat.of().formatHex(registration_lock_key)); AccountsHelper.setupMockUpdate(accountsManager); @@ -1019,7 +1020,8 @@ class AccountControllerTest { .target("/v1/accounts/code/666666") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar")) - .put(Entity.entity(new AccountAttributes(false, 3333, null, Hex.toStringCondensed(registration_lock_key), true, null), + .put(Entity.entity( + new AccountAttributes(false, 3333, null, HexFormat.of().formatHex(registration_lock_key), true, null), MediaType.APPLICATION_JSON_TYPE), AccountIdentityResponse.class); assertThat(result.uuid()).isNotNull(); @@ -1043,7 +1045,8 @@ class AccountControllerTest { .target("/v1/accounts/code/666666") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar")) - .put(Entity.entity(new AccountAttributes(false, 3333, null, Hex.toStringCondensed(registration_lock_key), true, null), + .put(Entity.entity( + new AccountAttributes(false, 3333, null, HexFormat.of().formatHex(registration_lock_key), true, null), MediaType.APPLICATION_JSON_TYPE), AccountIdentityResponse.class); assertThat(result.uuid()).isNotNull(); @@ -1051,7 +1054,7 @@ class AccountControllerTest { verify(pinLimiter).validate(eq(SENDER_REG_LOCK)); verify(accountsManager).create(eq(SENDER_REG_LOCK), eq("bar"), any(), argThat( - attributes -> Hex.toStringCondensed(registration_lock_key).equals(attributes.getRegistrationLock())), + attributes -> HexFormat.of().formatHex(registration_lock_key).equals(attributes.getRegistrationLock())), argThat(List::isEmpty)); } @@ -1104,7 +1107,7 @@ class AccountControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar")) .put(Entity.entity(new AccountAttributes(false, 3333, null, - Hex.toStringCondensed(new byte[32]), true, null), + HexFormat.of().formatHex(new byte[32]), true, null), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(423); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ProfileControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ProfileControllerTest.java index d435ea25a..53e9c54de 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ProfileControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ProfileControllerTest.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.Optional; @@ -47,7 +48,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.RandomStringUtils; import org.assertj.core.api.Condition; import org.glassfish.jersey.server.ServerProperties; @@ -945,7 +945,8 @@ class ProfileControllerTest { .thenReturn(credentialResponse); final ProfileKeyCredentialProfileResponse profile = resources.getJerseyTest() - .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize()))) + .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, + HexFormat.of().formatHex(credentialRequest.serialize()))) .request() .headers(authHeaders) .get(ProfileKeyCredentialProfileResponse.class); @@ -1029,7 +1030,8 @@ class ProfileControllerTest { .thenReturn(credentialResponse); final PniCredentialProfileResponse profile = resources.getJerseyTest() - .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize()))) + .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, + HexFormat.of().formatHex(credentialRequest.serialize()))) .queryParam("credentialType", "pni") .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) @@ -1078,7 +1080,8 @@ class ProfileControllerTest { .thenReturn(credentialResponse); final Response response = resources.getJerseyTest() - .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize()))) + .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, + HexFormat.of().formatHex(credentialRequest.serialize()))) .queryParam("credentialType", "pni") .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO)) @@ -1135,7 +1138,8 @@ class ProfileControllerTest { .thenReturn(credentialResponse); final ExpiringProfileKeyCredentialProfileResponse profile = resources.getJerseyTest() - .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize()))) + .target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, + HexFormat.of().formatHex(credentialRequest.serialize()))) .queryParam("credentialType", "expiringProfileKey") .request() .headers(authHeaders) diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java index 42e50643b..19ff99867 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java @@ -14,13 +14,13 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; -import org.apache.commons.codec.binary.Base64; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -117,7 +117,7 @@ public class ChangeNumberManagerTest { final IncomingMessage msg = mock(IncomingMessage.class); when(msg.destinationDeviceId()).thenReturn(2L); - when(msg.content()).thenReturn(Base64.encodeBase64String(new byte[]{1})); + when(msg.content()).thenReturn(Base64.getEncoder().encodeToString(new byte[]{1})); changeNumberManager.changeNumber(account, changedE164, pniIdentityKey, prekeys, List.of(msg), registrationIds);