Unify our Base64 utilities.

This commit is contained in:
Greyson Parrelli
2023-10-13 09:36:29 -07:00
committed by Cody Henthorne
parent e636e38ba1
commit 4fe6d79fff
122 changed files with 549 additions and 542 deletions

View File

@@ -81,8 +81,7 @@ import org.whispersystems.signalservice.internal.storage.protos.WriteOperation;
import org.whispersystems.signalservice.internal.util.StaticCredentialsProvider;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper;
import org.whispersystems.util.Base64;
import org.whispersystems.util.Base64UrlSafe;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.security.KeyStore;
@@ -801,7 +800,7 @@ public class SignalServiceAccountManager {
public UsernameLinkComponents createUsernameLink(Username username) throws IOException {
try {
UsernameLink link = username.generateLink();
UUID serverId = this.pushServiceSocket.createUsernameLink(Base64UrlSafe.encodeBytes(link.getEncryptedUsername()));
UUID serverId = this.pushServiceSocket.createUsernameLink(Base64.encodeUrlSafeWithPadding(link.getEncryptedUsername()));
return new UsernameLinkComponents(link.getEntropy(), serverId);
} catch (BaseUsernameException e) {
@@ -841,7 +840,7 @@ public class SignalServiceAccountManager {
try {
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] token = Util.trim(digest.digest(e164number.getBytes()), 10);
String encoded = Base64.encodeBytesWithoutPadding(token);
String encoded = Base64.encodeWithoutPadding(token);
if (urlSafe) return encoded.replace('+', '-').replace('/', '_');
else return encoded;

View File

@@ -127,7 +127,7 @@ import org.whispersystems.signalservice.internal.push.http.PartialSendBatchCompl
import org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener;
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.util.ByteArrayUtil;
import java.io.IOException;
@@ -888,7 +888,7 @@ public class SignalServiceMessageSender {
throws IOException, UntrustedIdentityException
{
byte[] nullMessageBody = new DataMessage.Builder()
.body(Base64.encodeBytes(Util.getRandomLengthBytes(140)))
.body(Base64.encodeWithPadding(Util.getRandomLengthBytes(140)))
.build()
.encode();
@@ -918,7 +918,7 @@ public class SignalServiceMessageSender {
throws UntrustedIdentityException, IOException
{
byte[] nullMessageBody = new DataMessage.Builder()
.body(Base64.encodeBytes(Util.getRandomLengthBytes(140)))
.body(Base64.encodeWithPadding(Util.getRandomLengthBytes(140)))
.build()
.encode();

View File

@@ -11,7 +11,7 @@ import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage;
import org.whispersystems.signalservice.internal.websocket.WebSocketResponseMessage;
import org.whispersystems.signalservice.internal.websocket.WebsocketResponse;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.ArrayList;
@@ -201,7 +201,7 @@ public final class SignalWebSocket {
public Single<WebsocketResponse> request(WebSocketRequestMessage requestMessage, Optional<UnidentifiedAccess> unidentifiedAccess) {
if (unidentifiedAccess.isPresent()) {
List<String> headers = new ArrayList<>(requestMessage.headers);
headers.add("Unidentified-Access-Key:" + Base64.encodeBytes(unidentifiedAccess.get().getUnidentifiedAccessKey()));
headers.add("Unidentified-Access-Key:" + Base64.encodeWithPadding(unidentifiedAccess.get().getUnidentifiedAccessKey()));
WebSocketRequestMessage message = requestMessage.newBuilder()
.headers(headers)
.build();

View File

@@ -13,7 +13,7 @@ import org.whispersystems.signalservice.internal.push.Content;
import org.whispersystems.signalservice.internal.push.Envelope.Type;
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage;
import org.whispersystems.signalservice.internal.push.PushTransportDetails;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.util.Optional;
@@ -88,7 +88,7 @@ public interface EnvelopeContent {
groupId);
byte[] ciphertext = sealedSessionCipher.encrypt(destination, messageContent);
String body = Base64.encodeBytes(ciphertext);
String body = Base64.encodeWithPadding(ciphertext);
int remoteRegistrationId = sealedSessionCipher.getRemoteRegistrationId(destination);
return new OutgoingPushMessage(Type.UNIDENTIFIED_SENDER.getValue(), destination.getDeviceId(), remoteRegistrationId, body);
@@ -99,7 +99,7 @@ public interface EnvelopeContent {
PushTransportDetails transportDetails = new PushTransportDetails();
CiphertextMessage message = sessionCipher.encrypt(transportDetails.getPaddedMessageBody(content.encode()));
int remoteRegistrationId = sessionCipher.getRemoteRegistrationId();
String body = Base64.encodeBytes(message.serialize());
String body = Base64.encodeWithPadding(message.serialize());
int type;
@@ -146,7 +146,7 @@ public interface EnvelopeContent {
groupId);
byte[] ciphertext = sealedSessionCipher.encrypt(destination, messageContent);
String body = Base64.encodeBytes(ciphertext);
String body = Base64.encodeWithPadding(ciphertext);
int remoteRegistrationId = sealedSessionCipher.getRemoteRegistrationId(destination);
return new OutgoingPushMessage(Type.UNIDENTIFIED_SENDER.getValue(), destination.getDeviceId(), remoteRegistrationId, body);
@@ -154,7 +154,7 @@ public interface EnvelopeContent {
@Override
public OutgoingPushMessage processUnsealedSender(SignalSessionCipher sessionCipher, SignalProtocolAddress destination) {
String body = Base64.encodeBytes(plaintextContent.serialize());
String body = Base64.encodeWithPadding(plaintextContent.serialize());
int remoteRegistrationId = sessionCipher.getRemoteRegistrationId();
return new OutgoingPushMessage(Type.PLAINTEXT_CONTENT.getValue(), destination.getDeviceId(), remoteRegistrationId, body);

View File

@@ -2,7 +2,7 @@ package org.whispersystems.signalservice.api.kbs;
import org.whispersystems.signalservice.api.storage.StorageKey;
import org.whispersystems.signalservice.internal.util.Hex;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.util.StringUtil;
import java.security.SecureRandom;
@@ -33,7 +33,7 @@ public final class MasterKey {
}
public String deriveRegistrationRecoveryPassword() {
return Base64.encodeBytes(derive("Registration Recovery"));
return Base64.encodeWithPadding(derive("Registration Recovery"));
}
public StorageKey deriveStorageServiceKey() {

View File

@@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.whispersystems.signalservice.internal.push.PreKeyEntity;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
@@ -43,7 +43,7 @@ public class SignedPreKeyEntity extends PreKeyEntity {
private static class ByteArraySerializer extends JsonSerializer<byte[]> {
@Override
public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytesWithoutPadding(value));
gen.writeString(Base64.encodeWithoutPadding(value));
}
}
@@ -51,7 +51,7 @@ public class SignedPreKeyEntity extends PreKeyEntity {
@Override
public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return Base64.decodeWithoutPadding(p.getValueAsString());
return Base64.decode(p.getValueAsString());
}
}
}

View File

@@ -22,7 +22,7 @@ import org.whispersystems.signalservice.internal.util.BlacklistingTrustManager;
import org.whispersystems.signalservice.internal.util.Hex;
import org.whispersystems.signalservice.internal.util.JsonUtil;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -214,7 +214,7 @@ final class CdsiSocket {
}
private static String basicAuth(String username, String password) {
return "Basic " + Base64.encodeBytes((username + ":" + password).getBytes(StandardCharsets.UTF_8));
return "Basic " + Base64.encodeWithPadding((username + ":" + password).getBytes(StandardCharsets.UTF_8));
}
private static Pair<SSLSocketFactory, X509TrustManager> createTlsSocketFactory(TrustStore trustStore) {

View File

@@ -19,7 +19,7 @@ import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper;
import org.whispersystems.signalservice.internal.websocket.ResponseMapper;
import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.security.SecureRandom;
import java.util.LinkedList;
@@ -74,7 +74,7 @@ public class MessagingService {
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent, boolean story) {
List<String> headers = new LinkedList<String>() {{
add("content-type:application/vnd.signal-messenger.mrm");
add("Unidentified-Access-Key:" + Base64.encodeBytes(joinedUnidentifiedAccess));
add("Unidentified-Access-Key:" + Base64.encodeWithPadding(joinedUnidentifiedAccess));
}};
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s&story=%s", timestamp, online, urgent, story);

View File

@@ -1,7 +1,7 @@
package org.whispersystems.signalservice.api.storage;
import org.whispersystems.signalservice.api.kbs.MasterKey;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.util.StringUtil;
import java.util.Arrays;
@@ -31,7 +31,7 @@ public final class StorageKey {
}
public StorageItemKey deriveItemKey(byte[] key) {
return new StorageItemKey(derive("Item_" + Base64.encodeBytes(key)));
return new StorageItemKey(derive("Item_" + Base64.encodeWithPadding(key)));
}
private byte[] derive(String keyName) {

View File

@@ -1,8 +1,8 @@
package org.whispersystems.signalservice.api.subscriptions;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.util.Preconditions;
import org.whispersystems.util.Base64UrlSafe;
import java.security.SecureRandom;
import java.util.Arrays;
@@ -25,7 +25,7 @@ public final class IdempotencyKey {
}
public String serialize() {
return Base64UrlSafe.encodeBytes(bytes);
return Base64.encodeUrlSafeWithPadding(bytes);
}
public static IdempotencyKey fromBytes(byte[] bytes) {

View File

@@ -1,8 +1,8 @@
package org.whispersystems.signalservice.api.subscriptions;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.util.Preconditions;
import org.whispersystems.util.Base64UrlSafe;
import java.security.SecureRandom;
import java.util.Arrays;
@@ -27,7 +27,7 @@ public final class SubscriberId {
}
public @NonNull String serialize() {
return Base64UrlSafe.encodeBytes(bytes);
return Base64.encodeUrlSafeWithPadding(bytes);
}
public static SubscriberId fromBytes(byte[] bytes) {

View File

@@ -1,6 +1,6 @@
package org.whispersystems.signalservice.internal.contacts.crypto;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.ByteArrayInputStream;
import java.security.InvalidAlgorithmParameterException;

View File

@@ -3,7 +3,7 @@ package org.whispersystems.signalservice.internal.push;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequest;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
class BoostReceiptCredentialRequestJson {
@JsonProperty("paymentIntentId")
@@ -17,7 +17,7 @@ class BoostReceiptCredentialRequestJson {
BoostReceiptCredentialRequestJson(String paymentIntentId, ReceiptCredentialRequest receiptCredentialRequest, DonationProcessor processor) {
this.paymentIntentId = paymentIntentId;
this.receiptCredentialRequest = Base64.encodeBytes(receiptCredentialRequest.serialize());
this.receiptCredentialRequest = Base64.encodeWithPadding(receiptCredentialRequest.serialize());
this.processor = processor.getCode();
}
}

View File

@@ -6,8 +6,8 @@
package org.whispersystems.signalservice.internal.push
import com.fasterxml.jackson.annotation.JsonCreator
import org.signal.core.util.Base64
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialRequest
import org.whispersystems.util.Base64
/**
* Request body to create a call link credential response.
@@ -19,7 +19,7 @@ data class CreateCallLinkAuthRequest @JsonCreator constructor(
@JvmStatic
fun create(createCallLinkCredentialRequest: CreateCallLinkCredentialRequest): CreateCallLinkAuthRequest {
return CreateCallLinkAuthRequest(
Base64.encodeBytes(createCallLinkCredentialRequest.serialize())
Base64.encodeWithPadding(createCallLinkCredentialRequest.serialize())
)
}
}

View File

@@ -7,8 +7,8 @@ package org.whispersystems.signalservice.internal.push
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty
import org.signal.core.util.Base64
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialResponse
import org.whispersystems.util.Base64
/**
* Response body for CreateCallLinkAuthResponse

View File

@@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.libsignal.protocol.IdentityKey;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.internal.util.JsonUtil;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -40,7 +40,7 @@ public class IdentityCheckRequest {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
this.fingerprint = Base64.encodeBytes(messageDigest.digest(identityKey.serialize()), 0, 4);
this.fingerprint = Base64.encodeWithPadding(messageDigest.digest(identityKey.serialize()), 0, 4);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}

View File

@@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.kem.KEMPublicKey;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
@@ -60,7 +60,7 @@ public class KyberPreKeyEntity {
private static class KEMPublicKeySerializer extends JsonSerializer<KEMPublicKey> {
@Override
public void serialize(KEMPublicKey value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytesWithoutPadding(value.serialize()));
gen.writeString(Base64.encodeWithoutPadding(value.serialize()));
}
}
@@ -68,7 +68,7 @@ public class KyberPreKeyEntity {
@Override
public KEMPublicKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
try {
return new KEMPublicKey(Base64.decodeWithoutPadding(p.getValueAsString()), 0);
return new KEMPublicKey(Base64.decode(p.getValueAsString()), 0);
} catch (InvalidKeyException e) {
throw new IOException(e);
}
@@ -78,7 +78,7 @@ public class KyberPreKeyEntity {
private static class ByteArraySerializer extends JsonSerializer<byte[]> {
@Override
public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytesWithoutPadding(value));
gen.writeString(Base64.encodeWithoutPadding(value));
}
}
@@ -86,7 +86,7 @@ public class KyberPreKeyEntity {
@Override
public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return Base64.decodeWithoutPadding(p.getValueAsString());
return Base64.decode(p.getValueAsString());
}
}
}

View File

@@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
@@ -51,7 +51,7 @@ public class PreKeyEntity {
private static class ECPublicKeySerializer extends JsonSerializer<ECPublicKey> {
@Override
public void serialize(ECPublicKey value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytesWithoutPadding(value.serialize()));
gen.writeString(Base64.encodeWithoutPadding(value.serialize()));
}
}
@@ -59,7 +59,7 @@ public class PreKeyEntity {
@Override
public ECPublicKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
try {
return Curve.decodePoint(Base64.decodeWithoutPadding(p.getValueAsString()), 0);
return Curve.decodePoint(Base64.decode(p.getValueAsString()), 0);
} catch (InvalidKeyException e) {
throw new IOException(e);
}

View File

@@ -142,8 +142,7 @@ import org.whispersystems.signalservice.internal.util.concurrent.FutureTransform
import org.whispersystems.signalservice.internal.util.concurrent.ListenableFuture;
import org.whispersystems.signalservice.internal.util.concurrent.SettableFuture;
import org.whispersystems.signalservice.internal.websocket.ResponseMapper;
import org.whispersystems.util.Base64;
import org.whispersystems.util.Base64UrlSafe;
import org.signal.core.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -429,8 +428,8 @@ public class PushServiceSocket {
RegistrationSessionRequestBody body = new RegistrationSessionRequestBody(sessionId,
recoveryPassword,
attributes,
Base64.encodeBytesWithoutPadding(aciPreKeys.getIdentityKey().serialize()),
Base64.encodeBytesWithoutPadding(pniPreKeys.getIdentityKey().serialize()),
Base64.encodeWithoutPadding(aciPreKeys.getIdentityKey().serialize()),
Base64.encodeWithoutPadding(pniPreKeys.getIdentityKey().serialize()),
aciSignedPreKey,
pniSignedPreKey,
aciLastResortKyberPreKey,
@@ -510,7 +509,7 @@ public class PushServiceSocket {
public void sendProvisioningMessage(String destination, byte[] body) throws IOException {
makeServiceRequest(String.format(PROVISIONING_MESSAGE_PATH, destination), "PUT",
JsonUtil.toJson(new ProvisioningMessage(Base64.encodeBytes(body))));
JsonUtil.toJson(new ProvisioningMessage(Base64.encodeWithPadding(body))));
}
public void registerGcmId(@Nonnull String gcmRegistrationId) throws IOException {
@@ -560,7 +559,7 @@ public class PushServiceSocket {
Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(String.format("%s%s", connectionHolder.getUrl(), path));
requestBuilder.put(RequestBody.create(MediaType.get("application/vnd.signal-messenger.mrm"), body));
requestBuilder.addHeader("Unidentified-Access-Key", Base64.encodeBytes(joinedUnidentifiedAccess));
requestBuilder.addHeader("Unidentified-Access-Key", Base64.encodeWithPadding(joinedUnidentifiedAccess));
if (signalAgent != null) {
requestBuilder.addHeader("X-Signal-Agent", signalAgent);
@@ -1071,7 +1070,7 @@ public class PushServiceSocket {
byte[] proof = Username.generateProof(username, randomness);
ConfirmUsernameRequest confirmUsernameRequest = new ConfirmUsernameRequest(reserveUsernameResponse.getUsernameHash(),
Base64UrlSafe.encodeBytesWithoutPadding(proof));
Base64.encodeUrlSafeWithoutPadding(proof));
makeServiceRequest(CONFIRM_USERNAME_PATH, "PUT", JsonUtil.toJson(confirmUsernameRequest), NO_HEADERS, (responseCode, body) -> {
switch (responseCode) {
@@ -1115,7 +1114,7 @@ public class PushServiceSocket {
String response = makeServiceRequestWithoutAuthentication(String.format(USERNAME_FROM_LINK_PATH, serverId.toString()), "GET", null);
GetUsernameFromLinkResponseBody parsed = JsonUtil.fromJson(response, GetUsernameFromLinkResponseBody.class);
return Base64UrlSafe.decodePaddingAgnostic(parsed.getUsernameLinkEncryptedValue());
return Base64.decode(parsed.getUsernameLinkEncryptedValue());
}
public void deleteAccount() throws IOException {
@@ -1137,7 +1136,7 @@ public class PushServiceSocket {
}
public void redeemDonationReceipt(ReceiptCredentialPresentation receiptCredentialPresentation, boolean visible, boolean primary) throws IOException {
String payload = JsonUtil.toJson(new RedeemReceiptRequest(Base64.encodeBytes(receiptCredentialPresentation.serialize()), visible, primary));
String payload = JsonUtil.toJson(new RedeemReceiptRequest(Base64.encodeWithPadding(receiptCredentialPresentation.serialize()), visible, primary));
makeServiceRequest(DONATION_REDEEM_RECEIPT, "POST", payload);
}
@@ -2097,7 +2096,7 @@ public class PushServiceSocket {
if (!headers.containsKey("Authorization") && !doNotAddAuthenticationOrUnidentifiedAccessKey) {
if (unidentifiedAccess.isPresent()) {
request.addHeader("Unidentified-Access-Key", Base64.encodeBytes(unidentifiedAccess.get().getUnidentifiedAccessKey()));
request.addHeader("Unidentified-Access-Key", Base64.encodeWithPadding(unidentifiedAccess.get().getUnidentifiedAccessKey()));
} else if (credentialsProvider.getPassword() != null) {
request.addHeader("Authorization", getAuthorizationHeader(credentialsProvider));
}
@@ -2395,7 +2394,7 @@ public class PushServiceSocket {
if (credentialsProvider.getDeviceId() != SignalServiceAddress.DEFAULT_DEVICE_ID) {
identifier += "." + credentialsProvider.getDeviceId();
}
return "Basic " + Base64.encodeBytes((identifier + ":" + credentialsProvider.getPassword()).getBytes("UTF-8"));
return "Basic " + Base64.encodeWithPadding((identifier + ":" + credentialsProvider.getPassword()).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
@@ -2663,7 +2662,7 @@ public class PushServiceSocket {
String path;
if (groupLinkPassword.isPresent()) {
path = String.format(GROUPSV2_GROUP_PASSWORD, Base64UrlSafe.encodeBytesWithoutPadding(groupLinkPassword.get()));
path = String.format(GROUPSV2_GROUP_PASSWORD, Base64.encodeUrlSafeWithoutPadding(groupLinkPassword.get()));
} else {
path = GROUPSV2_GROUP;
}
@@ -2719,7 +2718,7 @@ public class PushServiceSocket {
public GroupJoinInfo getGroupJoinInfo(Optional<byte[]> groupLinkPassword, GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, IOException, MalformedResponseException
{
String passwordParam = groupLinkPassword.map(Base64UrlSafe::encodeBytesWithoutPadding).orElse("");
String passwordParam = groupLinkPassword.map(org.signal.core.util.Base64::encodeUrlSafeWithoutPadding).orElse("");
try (Response response = makeStorageRequest(authorization.toString(),
String.format(GROUPSV2_GROUP_JOIN, passwordParam),
"GET",

View File

@@ -3,13 +3,13 @@ package org.whispersystems.signalservice.internal.push;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequest;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
class ReceiptCredentialRequestJson {
@JsonProperty("receiptCredentialRequest")
private final String receiptCredentialRequest;
ReceiptCredentialRequestJson(ReceiptCredentialRequest receiptCredentialRequest) {
this.receiptCredentialRequest = Base64.encodeBytes(receiptCredentialRequest.serialize());
this.receiptCredentialRequest = Base64.encodeWithPadding(receiptCredentialRequest.serialize());
}
}

View File

@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialResponse;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;

View File

@@ -11,7 +11,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
@@ -31,7 +31,7 @@ public class SenderCertificate {
public static class ByteArraySerializer extends JsonSerializer<byte[]> {
@Override
public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytes(value));
gen.writeString(Base64.encodeWithPadding(value));
}
}

View File

@@ -2,7 +2,7 @@ package org.whispersystems.signalservice.internal.push.http;
import org.signal.protos.resumableuploads.ResumableUpload;
import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.HashMap;
@@ -85,7 +85,7 @@ public final class ResumableUploadSpec {
.collect(Collectors.toList())
);
return Base64.encodeBytes(builder.build().encode());
return Base64.encodeWithPadding(builder.build().encode());
}
public static ResumableUploadSpec deserialize(String serializedSpec) throws ResumeLocationInvalidException {

View File

@@ -27,7 +27,7 @@ import org.whispersystems.signalservice.api.push.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.UUID;
@@ -98,7 +98,7 @@ public class JsonUtil {
public void serialize(IdentityKey value, JsonGenerator gen, SerializerProvider serializers)
throws IOException
{
gen.writeString(Base64.encodeBytesWithoutPadding(value.serialize()));
gen.writeString(Base64.encodeWithoutPadding(value.serialize()));
}
}
@@ -106,7 +106,7 @@ public class JsonUtil {
@Override
public IdentityKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
try {
return new IdentityKey(Base64.decodeWithoutPadding(p.getValueAsString()), 0);
return new IdentityKey(Base64.decode(p.getValueAsString()), 0);
} catch (InvalidKeyException e) {
throw new IOException(e);
}
@@ -164,7 +164,7 @@ public class JsonUtil {
public static class MasterKeySerializer extends JsonSerializer<MasterKey> {
@Override
public void serialize(MasterKey value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Base64.encodeBytes(value.serialize()));
gen.writeString(Base64.encodeWithPadding(value.serialize()));
}
}

View File

@@ -1,34 +0,0 @@
package org.whispersystems.util;
import java.io.IOException;
public final class Base64UrlSafe {
private Base64UrlSafe() {
}
public static byte[] decode(String s) throws IOException {
return Base64.decode(s, Base64.URL_SAFE);
}
public static byte[] decodePaddingAgnostic(String s) throws IOException {
switch (s.length() % 4) {
case 1:
case 3: s = s + "="; break;
case 2: s = s + "=="; break;
}
return decode(s);
}
public static String encodeBytes(byte[] source) {
try {
return Base64.encodeBytes(source, Base64.URL_SAFE);
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static String encodeBytesWithoutPadding(byte[] source) {
return encodeBytes(source).replace("=", "");
}
}

View File

@@ -6,7 +6,7 @@ import org.junit.Test;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -120,7 +120,7 @@ public class ProfileCipherTest {
ProfileCipher cipher = new ProfileCipher(key);
byte[] name = cipher.encrypt("Peter\0Parker".getBytes(), 53);
String encoded = Base64.encodeBytes(name);
String encoded = Base64.encodeWithPadding(name);
assertEquals(108, encoded.length());
}
@@ -131,7 +131,7 @@ public class ProfileCipherTest {
ProfileCipher cipher = new ProfileCipher(key);
byte[] name = cipher.encrypt("Peter\0Parker".getBytes(), 257);
String encoded = Base64.encodeBytes(name);
String encoded = Base64.encodeWithPadding(name);
assertEquals(380, encoded.length());
}

View File

@@ -4,7 +4,7 @@ import junit.framework.TestCase;
import org.conscrypt.Conscrypt;
import org.whispersystems.signalservice.internal.contacts.crypto.SigningCertificate;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.net.URLDecoder;
@@ -54,7 +54,7 @@ public class SigningCertificateTest extends TestCase {
malformedSignature[i] ^= (0x01 << j);
try {
certificate.verifySignature(signatureBody, Base64.encodeBytes(malformedSignature));
certificate.verifySignature(signatureBody, Base64.encodeWithPadding(malformedSignature));
throw new AssertionError("Signature verification should fail!");
} catch (SignatureException e) {
// good

View File

@@ -1,67 +0,0 @@
package org.whispersystems.util;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.whispersystems.signalservice.internal.util.Hex;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public final class Base64UrlSafeTest {
private final byte[] data;
private final String encoded;
private final String encodedWithoutPadding;
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{ "", "", "" },
{ "01", "AQ==", "AQ" },
{ "0102", "AQI=", "AQI" },
{ "010203", "AQID", "AQID" },
{ "030405", "AwQF", "AwQF" },
{ "03040506", "AwQFBg==", "AwQFBg" },
{ "0304050708", "AwQFBwg=", "AwQFBwg" },
{ "af4d6cff", "r01s_w==", "r01s_w" },
{ "ffefde", "_-_e", "_-_e" },
});
}
public Base64UrlSafeTest(String hexData, String encoded, String encodedWithoutPadding) throws IOException {
this.data = Hex.fromStringCondensed(hexData);
this.encoded = encoded;
this.encodedWithoutPadding = encodedWithoutPadding;
}
@Test
public void encodes_as_expected() {
assertEquals(encoded, Base64UrlSafe.encodeBytes(data));
}
@Test
public void encodes_as_expected_without_padding() {
assertEquals(encodedWithoutPadding, Base64UrlSafe.encodeBytesWithoutPadding(data));
}
@Test
public void decodes_as_expected() throws IOException {
assertArrayEquals(data, Base64UrlSafe.decode(encoded));
}
@Test
public void decodes_padding_agnostic_as_expected() throws IOException {
assertArrayEquals(data, Base64UrlSafe.decodePaddingAgnostic(encoded));
}
@Test
public void decodes_as_expected_without_padding() throws IOException {
assertArrayEquals(data, Base64UrlSafe.decodePaddingAgnostic(encodedWithoutPadding));
}
}