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

@ -14,6 +14,7 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.signal.core.util.Base64
import org.signal.core.util.SqlUtil
import org.signal.core.util.exists
import org.signal.core.util.requireLong
@ -39,7 +40,6 @@ import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.sms.IncomingTextMessage
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
import org.thoughtcrime.securesms.util.Util

View file

@ -13,6 +13,7 @@ import okio.ByteString
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.KbsEnclave
@ -23,7 +24,6 @@ import org.thoughtcrime.securesms.testing.Get
import org.thoughtcrime.securesms.testing.Verb
import org.thoughtcrime.securesms.testing.runSync
import org.thoughtcrime.securesms.testing.success
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.KeyBackupService
import org.whispersystems.signalservice.api.SignalServiceAccountManager
import org.whispersystems.signalservice.api.push.TrustStore

View file

@ -8,6 +8,7 @@ import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.signal.core.util.Base64
import org.signal.libsignal.usernames.Username
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.InstrumentationApplicationDependencyProvider
@ -20,7 +21,6 @@ import org.thoughtcrime.securesms.testing.failure
import org.thoughtcrime.securesms.testing.success
import org.whispersystems.signalservice.internal.push.ReserveUsernameResponse
import org.whispersystems.signalservice.internal.push.WhoAmIResponse
import org.whispersystems.util.Base64UrlSafe
@Suppress("ClassName")
@RunWith(AndroidJUnit4::class)
@ -58,13 +58,13 @@ class RefreshOwnProfileJob__checkUsernameIsInSyncTest {
Get("/v1/accounts/whoami") { r ->
MockResponse().success(
WhoAmIResponse().apply {
usernameHash = Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(serverUsername))
usernameHash = Base64.encodeUrlSafeWithoutPadding(Username.hash(serverUsername))
}
)
},
Put("/v1/accounts/username_hash/reserve") { r ->
didReserve = true
MockResponse().success(ReserveUsernameResponse(Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))))
MockResponse().success(ReserveUsernameResponse(Base64.encodeUrlSafeWithoutPadding(Username.hash(username))))
},
Put("/v1/accounts/username_hash/confirm") { r ->
didConfirm = true
@ -94,7 +94,7 @@ class RefreshOwnProfileJob__checkUsernameIsInSyncTest {
},
Put("/v1/accounts/username_hash/reserve") { r ->
didReserve = true
MockResponse().success(ReserveUsernameResponse(Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))))
MockResponse().success(ReserveUsernameResponse(Base64.encodeUrlSafeWithoutPadding(Username.hash(username))))
},
Put("/v1/accounts/username_hash/confirm") { r ->
didConfirm = true
@ -122,13 +122,13 @@ class RefreshOwnProfileJob__checkUsernameIsInSyncTest {
Get("/v1/accounts/whoami") { r ->
MockResponse().success(
WhoAmIResponse().apply {
usernameHash = Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))
usernameHash = Base64.encodeUrlSafeWithoutPadding(Username.hash(username))
}
)
},
Put("/v1/accounts/username_hash/reserve") { r ->
didReserve = true
MockResponse().success(ReserveUsernameResponse(Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))))
MockResponse().success(ReserveUsernameResponse(Base64.encodeUrlSafeWithoutPadding(Username.hash(username))))
},
Put("/v1/accounts/username_hash/confirm") { r ->
didConfirm = true
@ -156,7 +156,7 @@ class RefreshOwnProfileJob__checkUsernameIsInSyncTest {
Get("/v1/accounts/whoami") { r ->
MockResponse().success(
WhoAmIResponse().apply {
usernameHash = Base64UrlSafe.encodeBytesWithoutPadding(Username.hash("${username}23"))
usernameHash = Base64.encodeUrlSafeWithoutPadding(Username.hash("${username}23"))
}
)
},

View file

@ -6,12 +6,12 @@ import org.junit.Assert.assertNotEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.signal.core.util.Base64
import org.signal.core.util.update
import org.thoughtcrime.securesms.database.RecipientTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
import org.whispersystems.signalservice.api.push.ServiceId.ACI
@ -113,7 +113,7 @@ class ContactRecordProcessorTest {
private fun setStorageId(recipientId: RecipientId, storageId: StorageId) {
SignalDatabase.rawDatabase
.update(RecipientTable.TABLE_NAME)
.values(RecipientTable.STORAGE_SERVICE_ID to Base64.encodeBytes(storageId.raw))
.values(RecipientTable.STORAGE_SERVICE_ID to Base64.encodeWithPadding(storageId.raw))
.where("${RecipientTable.ID} = ?", recipientId)
.run()
}

View file

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.testing
import okio.ByteString.Companion.toByteString
import org.signal.core.util.Base64
import org.signal.libsignal.internal.Native
import org.signal.libsignal.internal.NativeHandleGuard
import org.signal.libsignal.metadata.certificate.CertificateValidator
@ -20,7 +21,6 @@ import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage
import org.whispersystems.util.Base64
import java.util.Optional
import java.util.UUID

View file

@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;

View file

@ -9,7 +9,7 @@ import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.blurhash.BlurHash;
import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.stickers.StickerLocator;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.InvalidMessageStructureException;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
@ -108,7 +108,7 @@ public class PointerAttachment extends Attachment {
String encodedKey = null;
if (pointer.get().asPointer().getKey() != null) {
encodedKey = Base64.encodeBytes(pointer.get().asPointer().getKey());
encodedKey = Base64.encodeWithPadding(pointer.get().asPointer().getKey());
}
return Optional.of(new PointerAttachment(pointer.get().getContentType(),
@ -144,7 +144,7 @@ public class PointerAttachment extends Attachment {
pointer.getFileName(),
thumbnail != null ? thumbnail.asPointer().getCdnNumber() : 0,
thumbnail != null ? thumbnail.asPointer().getRemoteId().toString() : "0",
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeBytes(thumbnail.asPointer().getKey()) : null,
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeWithPadding(thumbnail.asPointer().getKey()) : null,
null,
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,
@ -175,7 +175,7 @@ public class PointerAttachment extends Attachment {
quotedAttachment.fileName,
thumbnail != null ? thumbnail.asPointer().getCdnNumber() : 0,
thumbnail != null ? thumbnail.asPointer().getRemoteId().toString() : "0",
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeBytes(thumbnail.asPointer().getKey()) : null,
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeWithPadding(thumbnail.asPointer().getKey()) : null,
null,
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,

View file

@ -8,7 +8,7 @@ import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.database.model.databaseprotos.AudioWaveFormData;
import org.thoughtcrime.securesms.util.ParcelUtil;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.Objects;
@ -27,7 +27,7 @@ public final class AudioHash implements Parcelable {
}
public AudioHash(@NonNull AudioWaveFormData audioWaveForm) {
this(Base64.encodeBytes(audioWaveForm.encode()), audioWaveForm);
this(Base64.encodeWithPadding(audioWaveForm.encode()), audioWaveForm);
}
protected AudioHash(Parcel in) {

View file

@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.badges.gifts
import android.content.Context
import org.signal.core.util.Base64
import org.signal.libsignal.zkgroup.InvalidInputException
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge
import org.thoughtcrime.securesms.mms.OutgoingMessage
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.Base64
import java.lang.Integer.min
import java.util.concurrent.TimeUnit
@ -32,7 +32,7 @@ object Gifts {
): OutgoingMessage {
return OutgoingMessage(
threadRecipient = recipient,
body = Base64.encodeBytes(giftBadge.encode()),
body = Base64.encodeWithPadding(giftBadge.encode()),
isSecure = true,
sentTimeMillis = sentTimestamp,
expiresIn = expiresIn,

View file

@ -7,6 +7,7 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.signal.core.util.Base64
import org.signal.core.util.Hex
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.isAbsent
@ -27,7 +28,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.subscription.Subscriber
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.SpanUtil
import org.thoughtcrime.securesms.util.Util
@ -110,7 +110,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
summary = DSLSettingsText.from("[${recipient.profileName.givenName}] [${state.recipient.profileName.familyName}]")
)
val profileKeyBase64 = recipient.profileKey?.let(Base64::encodeBytes) ?: "None"
val profileKeyBase64 = recipient.profileKey?.let(Base64::encodeWithPadding) ?: "None"
longClickPref(
title = DSLSettingsText.from("Profile Key (Base64)"),
summary = DSLSettingsText.from(profileKeyBase64),

View file

@ -6,6 +6,7 @@ import android.text.Spannable
import android.text.SpannableString
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.Base64
import org.signal.core.util.StreamUtil
import org.signal.core.util.concurrent.MaybeCompat
import org.signal.core.util.concurrent.SignalExecutors
@ -41,7 +42,6 @@ import org.thoughtcrime.securesms.mms.SlideFactory
import org.thoughtcrime.securesms.mms.StickerSlide
import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor
import org.thoughtcrime.securesms.util.hasTextSlide

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import org.signal.core.util.Base64
import org.thoughtcrime.securesms.components.location.SignalPlace
import org.thoughtcrime.securesms.database.DraftTable.Draft
import org.thoughtcrime.securesms.database.MentionUtil
@ -12,7 +13,6 @@ import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.mms.QuoteId
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.rx.RxStore
/**
@ -148,5 +148,5 @@ private fun String.toTextDraft(): Draft? {
}
private fun BodyRangeList.toDraft(): Draft {
return Draft(Draft.BODY_RANGES, Base64.encodeBytes(encode()))
return Draft(Draft.BODY_RANGES, Base64.encodeWithPadding(encode()))
}

View file

@ -24,7 +24,7 @@ import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.signal.libsignal.protocol.ecc.ECPrivateKey;
import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@ -99,7 +99,7 @@ public class AsymmetricMasterCipher {
}
public String encryptBody(String body) {
return Base64.encodeBytes(encryptBytes(body.getBytes()));
return Base64.encodeWithPadding(encryptBytes(body.getBytes()));
}
private MasterCipher getMasterCipherForSecret(byte[] secretBytes) {

View file

@ -23,7 +23,7 @@ import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.InvalidMessageException;
import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECPrivateKey;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.signal.core.util.Hex;
import java.io.IOException;
@ -153,7 +153,7 @@ public class MasterCipher {
private String encryptAndEncodeBytes(@NonNull byte[] bytes) {
byte[] encryptedAndMacBody = encryptBytes(bytes);
return Base64.encodeBytes(encryptedAndMacBody);
return Base64.encodeWithPadding(encryptedAndMacBody);
}
private byte[] verifyMacBody(@NonNull Mac hmac, @NonNull byte[] encryptedAndMac) throws InvalidMessageException {

View file

@ -30,7 +30,7 @@ import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.signal.libsignal.protocol.ecc.ECPrivateKey;
import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@ -216,7 +216,7 @@ public class MasterSecretUtil {
private static void save(Context context, String key, byte[] value) {
if (!getSharedPreferences(context)
.edit()
.putString(key, Base64.encodeBytes(value))
.putString(key, Base64.encodeWithPadding(value))
.commit())
{
throw new AssertionError("failed to save a shared pref in MasterSecretUtil");

View file

@ -7,7 +7,7 @@ import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;

View file

@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;

View file

@ -37,6 +37,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.json.JSONArray;
import org.json.JSONException;
import org.signal.core.util.Base64;
import org.signal.core.util.CursorExtensionsKt;
import org.signal.core.util.CursorUtil;
import org.signal.core.util.SQLiteDatabaseExtensionsKt;
@ -60,7 +61,6 @@ import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.SentMediaQuality;
import org.thoughtcrime.securesms.stickers.StickerLocator;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
@ -1189,7 +1189,7 @@ public class AttachmentTable extends DatabaseTable {
DigestInputStream digestInputStream = new DigestInputStream(in, messageDigest);
Pair<byte[], OutputStream> out = ModernEncryptingPartOutputStream.createFor(attachmentSecret, tempFile, false);
long length = StreamUtil.copy(digestInputStream, out.second);
String hash = Base64.encodeBytes(digestInputStream.getMessageDigest().digest());
String hash = Base64.encodeWithPadding(digestInputStream.getMessageDigest().digest());
if (!tempFile.renameTo(destination)) {
Log.w(TAG, "Couldn't rename " + tempFile.getPath() + " to " + destination.getPath());

View file

@ -4,6 +4,7 @@ import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.delete
@ -23,7 +24,6 @@ import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.storage.StorageRecordUpdate
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.push.DistributionId
import org.whispersystems.signalservice.api.storage.SignalStoryDistributionListRecord
import org.whispersystems.signalservice.api.util.UuidUtil
@ -55,7 +55,7 @@ class DistributionListTables constructor(context: Context?, databaseHelper: Sign
contentValuesOf(
RecipientTable.TYPE to RecipientTable.RecipientType.DISTRIBUTION_LIST.id,
RecipientTable.DISTRIBUTION_LIST_ID to DistributionListId.MY_STORY_ID,
RecipientTable.STORAGE_SERVICE_ID to Base64.encodeBytes(StorageSyncHelper.generateKey()),
RecipientTable.STORAGE_SERVICE_ID to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
RecipientTable.PROFILE_SHARING to 1
)
)

View file

@ -19,6 +19,7 @@ package org.thoughtcrime.securesms.database
import android.content.Context
import androidx.core.content.contentValuesOf
import org.greenrobot.eventbus.EventBus
import org.signal.core.util.Base64
import org.signal.core.util.delete
import org.signal.core.util.exists
import org.signal.core.util.firstOrNull
@ -38,7 +39,6 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.IdentityUtil
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.util.UuidUtil
@ -146,7 +146,7 @@ class IdentityTable internal constructor(context: Context?, databaseHelper: Sign
val updated = writableDatabase
.update(TABLE_NAME)
.values(VERIFIED to verifiedStatus.toInt())
.where("$ADDRESS = ? AND $IDENTITY_KEY = ?", addressName, Base64.encodeBytes(identityKey.serialize()))
.where("$ADDRESS = ? AND $IDENTITY_KEY = ?", addressName, Base64.encodeWithPadding(identityKey.serialize()))
.run()
if (updated > 0) {
@ -211,14 +211,14 @@ class IdentityTable internal constructor(context: Context?, databaseHelper: Sign
private fun hasMatchingKey(addressName: String, identityKey: IdentityKey): Boolean {
return readableDatabase
.exists(TABLE_NAME)
.where("$ADDRESS = ? AND $IDENTITY_KEY = ?", addressName, Base64.encodeBytes(identityKey.serialize()))
.where("$ADDRESS = ? AND $IDENTITY_KEY = ?", addressName, Base64.encodeWithPadding(identityKey.serialize()))
.run()
}
private fun hasMatchingStatus(addressName: String, identityKey: IdentityKey, verifiedStatus: VerifiedStatus): Boolean {
return readableDatabase
.exists(TABLE_NAME)
.where("$ADDRESS = ? AND $IDENTITY_KEY = ? AND $VERIFIED = ?", addressName, Base64.encodeBytes(identityKey.serialize()), verifiedStatus.toInt())
.where("$ADDRESS = ? AND $IDENTITY_KEY = ? AND $VERIFIED = ?", addressName, Base64.encodeWithPadding(identityKey.serialize()), verifiedStatus.toInt())
.run()
}
@ -233,7 +233,7 @@ class IdentityTable internal constructor(context: Context?, databaseHelper: Sign
) {
val contentValues = contentValuesOf(
ADDRESS to addressName,
IDENTITY_KEY to Base64.encodeBytes(identityKey.serialize()),
IDENTITY_KEY to Base64.encodeWithPadding(identityKey.serialize()),
TIMESTAMP to timestamp,
VERIFIED to verifiedStatus.toInt(),
NONBLOCKING_APPROVAL to if (nonBlockingApproval) 1 else 0,

View file

@ -28,6 +28,7 @@ import com.google.android.mms.pdu_alt.PduHeaders
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.SqlUtil.appendArg
@ -131,7 +132,6 @@ import org.thoughtcrime.securesms.revealable.ViewOnceUtil
import org.thoughtcrime.securesms.sms.IncomingGroupUpdateMessage
import org.thoughtcrime.securesms.sms.IncomingTextMessage
import org.thoughtcrime.securesms.stories.Stories.isFeatureEnabled
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.JsonUtils
import org.thoughtcrime.securesms.util.MediaUtil
@ -861,7 +861,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
DATE_RECEIVED to timestamp,
DATE_SENT to timestamp,
READ to if (markRead) 1 else 0,
BODY to Base64.encodeBytes(updateDetails),
BODY to Base64.encodeWithPadding(updateDetails),
TYPE to MessageTypes.GROUP_CALL_TYPE,
THREAD_ID to threadId
)
@ -891,7 +891,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
val updateDetail = GroupCallUpdateDetailsUtil.parse(message.body)
val contentValues = contentValuesOf(
BODY to Base64.encodeBytes(updateDetail.newBuilder().startedCallTimestamp(timestamp).build().encode()),
BODY to Base64.encodeWithPadding(updateDetail.newBuilder().startedCallTimestamp(timestamp).build().encode()),
DATE_SENT to timestamp,
DATE_RECEIVED to timestamp
)
@ -1179,7 +1179,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
READ to 1,
TYPE to MessageTypes.PROFILE_CHANGE_TYPE,
THREAD_ID to threadId,
BODY to Base64.encodeBytes(profileChangeDetails)
BODY to Base64.encodeWithPadding(profileChangeDetails)
)
db.insert(TABLE_NAME, null, values)
notifyConversationListeners(threadId)
@ -1286,7 +1286,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
READ to 1,
TYPE to MessageTypes.THREAD_MERGE_TYPE,
THREAD_ID to threadId,
BODY to Base64.encodeBytes(event.encode())
BODY to Base64.encodeWithPadding(event.encode())
)
.run()
ApplicationDependencies.getDatabaseObserver().notifyConversationListeners(threadId)
@ -1305,7 +1305,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
READ to 1,
TYPE to MessageTypes.SESSION_SWITCHOVER_TYPE,
THREAD_ID to threadId,
BODY to Base64.encodeBytes(event.encode())
BODY to Base64.encodeWithPadding(event.encode())
)
.run()
ApplicationDependencies.getDatabaseObserver().notifyConversationListeners(threadId)
@ -2914,7 +2914,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
updated = db
.update(TABLE_NAME)
.values(BODY to Base64.encodeBytes(updatedBadge.encode()))
.values(BODY to Base64.encodeWithPadding(updatedBadge.encode()))
.where("$ID = ?", messageId)
.run() > 0

View file

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.database
import android.content.Context
import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.SqlUtil
import org.signal.core.util.delete
import org.signal.core.util.logging.Log
@ -11,7 +12,6 @@ import org.signal.libsignal.protocol.InvalidKeyException
import org.signal.libsignal.protocol.ecc.Curve
import org.signal.libsignal.protocol.ecc.ECKeyPair
import org.signal.libsignal.protocol.state.PreKeyRecord
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.push.ServiceId
import java.io.IOException
@ -62,8 +62,8 @@ class OneTimePreKeyTable(context: Context, databaseHelper: SignalDatabase) : Dat
val contentValues = contentValuesOf(
ACCOUNT_ID to serviceId.toString(),
KEY_ID to keyId,
PUBLIC_KEY to Base64.encodeBytes(record.keyPair.publicKey.serialize()),
PRIVATE_KEY to Base64.encodeBytes(record.keyPair.privateKey.serialize())
PUBLIC_KEY to Base64.encodeWithPadding(record.keyPair.publicKey.serialize()),
PRIVATE_KEY to Base64.encodeWithPadding(record.keyPair.privateKey.serialize())
)
writableDatabase.replace(TABLE_NAME, null, contentValues)

View file

@ -32,7 +32,7 @@ import org.thoughtcrime.securesms.payments.Payment;
import org.thoughtcrime.securesms.payments.State;
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.whispersystems.signalservice.api.payments.Money;
import org.whispersystems.signalservice.api.util.UuidUtil;
@ -239,7 +239,7 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
}
if (receipt != null) {
values.put(RECEIPT, receipt);
values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
values.put(PUBLIC_KEY, Base64.encodeWithPadding(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
} else {
values.putNull(RECEIPT);
values.putNull(PUBLIC_KEY);
@ -468,7 +468,7 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
values.put(TRANSACTION, transaction);
values.put(RECEIPT, receipt);
try {
values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
values.put(PUBLIC_KEY, Base64.encodeWithPadding(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
values.put(META_DATA, PaymentMetaDataUtil.fromReceiptAndTransaction(receipt, transaction).encode());
} catch (SerializationException e) {
throw new IllegalArgumentException(e);

View file

@ -10,6 +10,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.content.contentValuesOf
import app.cash.exhaustive.Exhaustive
import okio.ByteString.Companion.toByteString
import org.signal.core.util.Base64
import org.signal.core.util.Bitmask
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
@ -93,7 +94,6 @@ import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
import org.thoughtcrime.securesms.storage.StorageRecordUpdate
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.storage.StorageSyncModels
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.GroupUtil
import org.thoughtcrime.securesms.util.IdentityUtil
@ -530,7 +530,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
ContentValues().apply {
put(TYPE, RecipientType.DISTRIBUTION_LIST.id)
put(DISTRIBUTION_LIST_ID, distributionListId.serialize())
put(STORAGE_SERVICE_ID, Base64.encodeBytes(storageId ?: StorageSyncHelper.generateKey()))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(storageId ?: StorageSyncHelper.generateKey()))
put(PROFILE_SHARING, 1)
}
).recipientId
@ -596,7 +596,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
} else {
put(TYPE, RecipientType.GV1.id)
}
put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey()))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
}
@ -716,7 +716,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
fun getByStorageId(storageId: ByteArray): RecipientRecord? {
val result = getRecordForSync("$TABLE_NAME.$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeBytes(storageId)))
val result = getRecordForSync("$TABLE_NAME.$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeWithPadding(storageId)))
return if (result.isNotEmpty()) {
result[0]
@ -774,7 +774,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val query = "$ID = ?"
for ((key, value) in storageIds) {
val values = ContentValues().apply {
put(STORAGE_SERVICE_ID, Base64.encodeBytes(value.raw))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(value.raw))
}
db.update(TABLE_NAME, values, query, arrayOf(key.serialize()))
}
@ -826,13 +826,13 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val values = getValuesForStorageContact(update.new, false)
try {
val updateCount = db.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeBytes(update.old.id.raw)))
val updateCount = db.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeWithPadding(update.old.id.raw)))
if (updateCount < 1) {
throw AssertionError("Had an update, but it didn't match any rows!")
}
} catch (e: SQLiteConstraintException) {
Log.w(TAG, "[applyStorageSyncContactUpdate] Failed to update a user by storageId.")
var recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeBytes(update.old.id.raw)).get()
var recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeWithPadding(update.old.id.raw)).get()
Log.w(TAG, "[applyStorageSyncContactUpdate] Found user $recipientId. Possibly merging.")
recipientId = getAndPossiblyMergePnpVerified(update.new.aci.orElse(null), update.new.pni.orElse(null), update.new.number.orElse(null))
@ -885,7 +885,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
fun applyStorageSyncGroupV1Update(update: StorageRecordUpdate<SignalGroupV1Record>) {
val values = getValuesForStorageGroupV1(update.new, false)
val updateCount = writableDatabase.update(TABLE_NAME, values, STORAGE_SERVICE_ID + " = ?", arrayOf(Base64.encodeBytes(update.old.id.raw)))
val updateCount = writableDatabase.update(TABLE_NAME, values, STORAGE_SERVICE_ID + " = ?", arrayOf(Base64.encodeWithPadding(update.old.id.raw)))
if (updateCount < 1) {
throw AssertionError("Had an update, but it didn't match any rows!")
}
@ -929,7 +929,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
fun applyStorageSyncGroupV2Update(update: StorageRecordUpdate<SignalGroupV2Record>) {
val values = getValuesForStorageGroupV2(update.new, false)
val updateCount = writableDatabase.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeBytes(update.old.id.raw)))
val updateCount = writableDatabase.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeWithPadding(update.old.id.raw)))
if (updateCount < 1) {
throw AssertionError("Had an update, but it didn't match any rows!")
}
@ -951,7 +951,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val profileName = ProfileName.fromParts(update.new.givenName.orElse(null), update.new.familyName.orElse(null))
val localKey = ProfileKeyUtil.profileKeyOptional(update.old.profileKey.orElse(null))
val remoteKey = ProfileKeyUtil.profileKeyOptional(update.new.profileKey.orElse(null))
val profileKey: String? = remoteKey.or(localKey).map { obj: ProfileKey -> obj.serialize() }.map { source: ByteArray? -> Base64.encodeBytes(source!!) }.orElse(null)
val profileKey: String? = remoteKey.or(localKey).map { obj: ProfileKey -> obj.serialize() }.map { source: ByteArray? -> Base64.encodeWithPadding(source!!) }.orElse(null)
if (!remoteKey.isPresent) {
Log.w(TAG, "Got an empty profile key while applying an account record update! The parsed local key is ${if (localKey.isPresent) "present" else "not present"}. The raw local key is ${if (update.old.profileKey.isPresent) "present" else "not present"}. The resulting key is ${if (profileKey != null) "present" else "not present"}.")
}
@ -968,10 +968,10 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
put(USERNAME, update.new.username)
put(STORAGE_SERVICE_ID, Base64.encodeBytes(update.new.id.raw))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(update.new.id.raw))
if (update.new.hasUnknownFields()) {
put(STORAGE_SERVICE_PROTO, Base64.encodeBytes(Objects.requireNonNull(update.new.serializeUnknownFields())))
put(STORAGE_SERVICE_PROTO, Base64.encodeWithPadding(Objects.requireNonNull(update.new.serializeUnknownFields())))
} else {
putNull(STORAGE_SERVICE_PROTO)
}
@ -985,7 +985,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
.run()
}
val updateCount = writableDatabase.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeBytes(update.old.id.raw)))
val updateCount = writableDatabase.update(TABLE_NAME, values, "$STORAGE_SERVICE_ID = ?", arrayOf(Base64.encodeWithPadding(update.old.id.raw)))
if (updateCount < 1) {
throw AssertionError("Account update didn't match any rows!")
}
@ -1019,7 +1019,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val values = contentValuesOf(STORAGE_SERVICE_ID to null)
var updated = 0
SqlUtil.buildCollectionQuery(STORAGE_SERVICE_ID, storageIds.map { Base64.encodeBytes(it.raw) }, "$UNREGISTERED_TIMESTAMP > 0 AND")
SqlUtil.buildCollectionQuery(STORAGE_SERVICE_ID, storageIds.map { Base64.encodeWithPadding(it.raw) }, "$UNREGISTERED_TIMESTAMP > 0 AND")
.forEach {
updated += writableDatabase.update(TABLE_NAME, values, it.where, it.whereArgs)
}
@ -1048,7 +1048,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
private fun getByStorageKeyOrThrow(storageKey: ByteArray): RecipientId {
val query = "$STORAGE_SERVICE_ID = ?"
val args = arrayOf(Base64.encodeBytes(storageKey))
val args = arrayOf(Base64.encodeWithPadding(storageKey))
readableDatabase.query(TABLE_NAME, ID_PROJECTION, query, args, null, null, null).use { cursor ->
return if (cursor != null && cursor.moveToFirst()) {
@ -1500,7 +1500,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
fun setProfileKey(id: RecipientId, profileKey: ProfileKey): Boolean {
val selection = "$ID = ?"
val args = arrayOf(id.serialize())
val encodedProfileKey = Base64.encodeBytes(profileKey.serialize())
val encodedProfileKey = Base64.encodeWithPadding(profileKey.serialize())
val valuesToCompare = ContentValues(1).apply {
put(PROFILE_KEY, encodedProfileKey)
}
@ -1537,7 +1537,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val selection = "$ID = ? AND $PROFILE_KEY is NULL"
val args = arrayOf(id.serialize())
val valuesToSet = ContentValues(3).apply {
put(PROFILE_KEY, Base64.encodeBytes(profileKey.serialize()))
put(PROFILE_KEY, Base64.encodeWithPadding(profileKey.serialize()))
putNull(EXPIRING_PROFILE_KEY_CREDENTIAL)
put(SEALED_SENDER_MODE, UnidentifiedAccessMode.UNKNOWN.mode)
}
@ -1560,13 +1560,13 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
expiringProfileKeyCredential: ExpiringProfileKeyCredential
): Boolean {
val selection = "$ID = ? AND $PROFILE_KEY = ?"
val args = arrayOf(id.serialize(), Base64.encodeBytes(profileKey.serialize()))
val args = arrayOf(id.serialize(), Base64.encodeWithPadding(profileKey.serialize()))
val columnData = ExpiringProfileKeyCredentialColumnData.Builder()
.profileKey(profileKey.serialize().toByteString())
.expiringProfileKeyCredential(expiringProfileKeyCredential.serialize().toByteString())
.build()
val values = ContentValues(1).apply {
put(EXPIRING_PROFILE_KEY_CREDENTIAL, Base64.encodeBytes(columnData.encode()))
put(EXPIRING_PROFILE_KEY_CREDENTIAL, Base64.encodeWithPadding(columnData.encode()))
}
val updateQuery = SqlUtil.buildTrueUpdateQuery(selection, args, values)
@ -3492,7 +3492,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
try {
for ((key, value) in ids) {
val values = ContentValues().apply {
put(STORAGE_SERVICE_ID, Base64.encodeBytes(value!!))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(value!!))
}
db.update(TABLE_NAME, values, ID_WHERE, arrayOf(key.serialize()))
}
@ -3639,7 +3639,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
*/
fun rotateStorageId(recipientId: RecipientId) {
val values = ContentValues(1).apply {
put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey()))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
val query = "$ID = ? AND ($TYPE IN (?, ?, ?) OR $REGISTERED = ?)"
@ -3652,7 +3652,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
*/
fun setStorageIdIfNotSet(recipientId: RecipientId) {
val values = ContentValues(1).apply {
put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey()))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
val query = "$ID = ? AND $STORAGE_SERVICE_ID IS NULL"
@ -3840,7 +3840,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
E164 to e164,
ACI_COLUMN to aci?.toString(),
PNI_COLUMN to pni?.toString(),
STORAGE_SERVICE_ID to Base64.encodeBytes(StorageSyncHelper.generateKey()),
STORAGE_SERVICE_ID to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
AVATAR_COLOR to AvatarColorHash.forAddress((aci ?: pni)?.toString(), e164).serialize()
)
@ -3868,16 +3868,16 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
put(SYSTEM_FAMILY_NAME, systemName.familyName)
put(SYSTEM_JOINED_NAME, systemName.toString())
put(SYSTEM_NICKNAME, contact.systemNickname.orElse(null))
put(PROFILE_KEY, contact.profileKey.map { source -> Base64.encodeBytes(source) }.orElse(null))
put(PROFILE_KEY, contact.profileKey.map { source -> Base64.encodeWithPadding(source) }.orElse(null))
put(USERNAME, if (TextUtils.isEmpty(username)) null else username)
put(PROFILE_SHARING, if (contact.isProfileSharingEnabled) "1" else "0")
put(BLOCKED, if (contact.isBlocked) "1" else "0")
put(MUTE_UNTIL, contact.muteUntil)
put(STORAGE_SERVICE_ID, Base64.encodeBytes(contact.id.raw))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(contact.id.raw))
put(HIDDEN, contact.isHidden)
if (contact.hasUnknownFields()) {
put(STORAGE_SERVICE_PROTO, Base64.encodeBytes(Objects.requireNonNull(contact.serializeUnknownFields())))
put(STORAGE_SERVICE_PROTO, Base64.encodeWithPadding(Objects.requireNonNull(contact.serializeUnknownFields())))
} else {
putNull(STORAGE_SERVICE_PROTO)
}
@ -3906,10 +3906,10 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
put(PROFILE_SHARING, if (groupV1.isProfileSharingEnabled) "1" else "0")
put(BLOCKED, if (groupV1.isBlocked) "1" else "0")
put(MUTE_UNTIL, groupV1.muteUntil)
put(STORAGE_SERVICE_ID, Base64.encodeBytes(groupV1.id.raw))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(groupV1.id.raw))
if (groupV1.hasUnknownFields()) {
put(STORAGE_SERVICE_PROTO, Base64.encodeBytes(groupV1.serializeUnknownFields()))
put(STORAGE_SERVICE_PROTO, Base64.encodeWithPadding(groupV1.serializeUnknownFields()))
} else {
putNull(STORAGE_SERVICE_PROTO)
}
@ -3929,11 +3929,11 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
put(PROFILE_SHARING, if (groupV2.isProfileSharingEnabled) "1" else "0")
put(BLOCKED, if (groupV2.isBlocked) "1" else "0")
put(MUTE_UNTIL, groupV2.muteUntil)
put(STORAGE_SERVICE_ID, Base64.encodeBytes(groupV2.id.raw))
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(groupV2.id.raw))
put(MENTION_SETTING, if (groupV2.notifyForMentionsWhenMuted()) MentionSetting.ALWAYS_NOTIFY.id else MentionSetting.DO_NOT_NOTIFY.id)
if (groupV2.hasUnknownFields()) {
put(STORAGE_SERVICE_PROTO, Base64.encodeBytes(groupV2.serializeUnknownFields()))
put(STORAGE_SERVICE_PROTO, Base64.encodeWithPadding(groupV2.serializeUnknownFields()))
} else {
putNull(STORAGE_SERVICE_PROTO)
}
@ -4250,7 +4250,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
private fun updateProfileValuesForMerge(values: ContentValues, record: RecipientRecord) {
values.apply {
put(PROFILE_KEY, if (record.profileKey != null) Base64.encodeBytes(record.profileKey) else null)
put(PROFILE_KEY, if (record.profileKey != null) Base64.encodeWithPadding(record.profileKey) else null)
putNull(EXPIRING_PROFILE_KEY_CREDENTIAL)
put(PROFILE_AVATAR, record.signalProfileAvatar)
put(PROFILE_GIVEN_NAME, record.signalProfileName.givenName)

View file

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.database
import android.content.Context
import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.SqlUtil
import org.signal.core.util.logging.Log
import org.signal.core.util.requireInt
@ -11,7 +12,6 @@ import org.signal.libsignal.protocol.InvalidKeyException
import org.signal.libsignal.protocol.ecc.Curve
import org.signal.libsignal.protocol.ecc.ECKeyPair
import org.signal.libsignal.protocol.state.SignedPreKeyRecord
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.push.ServiceId
import java.io.IOException
import java.util.LinkedList
@ -88,9 +88,9 @@ class SignedPreKeyTable(context: Context, databaseHelper: SignalDatabase) : Data
val contentValues = contentValuesOf(
ACCOUNT_ID to serviceId.toString(),
KEY_ID to keyId,
PUBLIC_KEY to Base64.encodeBytes(record.keyPair.publicKey.serialize()),
PRIVATE_KEY to Base64.encodeBytes(record.keyPair.privateKey.serialize()),
SIGNATURE to Base64.encodeBytes(record.signature),
PUBLIC_KEY to Base64.encodeWithPadding(record.keyPair.publicKey.serialize()),
PRIVATE_KEY to Base64.encodeWithPadding(record.keyPair.privateKey.serialize()),
SIGNATURE to Base64.encodeWithPadding(record.signature),
TIMESTAMP to record.timestamp
)
writableDatabase.replace(TABLE_NAME, null, contentValues)

View file

@ -8,7 +8,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.CursorUtil;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.signal.core.util.SqlUtil;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import org.whispersystems.signalservice.api.storage.StorageId;
@ -84,7 +84,7 @@ public class UnknownStorageIdTable extends DatabaseTable {
public @Nullable SignalStorageRecord getById(@NonNull byte[] rawId) {
String query = STORAGE_ID + " = ?";
String[] args = new String[] { Base64.encodeBytes(rawId) };
String[] args = new String[] { Base64.encodeWithPadding(rawId) };
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, query, args, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
@ -104,7 +104,7 @@ public class UnknownStorageIdTable extends DatabaseTable {
for (SignalStorageRecord insert : inserts) {
ContentValues values = new ContentValues();
values.put(TYPE, insert.getType());
values.put(STORAGE_ID, Base64.encodeBytes(insert.getId().getRaw()));
values.put(STORAGE_ID, Base64.encodeWithPadding(insert.getId().getRaw()));
db.insert(TABLE_NAME, null, values);
}
@ -117,7 +117,7 @@ public class UnknownStorageIdTable extends DatabaseTable {
Preconditions.checkArgument(db.inTransaction(), "Must be in a transaction!");
for (StorageId id : deletes) {
String[] args = SqlUtil.buildArgs(Base64.encodeBytes(id.getRaw()));
String[] args = SqlUtil.buildArgs(Base64.encodeWithPadding(id.getRaw()));
db.delete(TABLE_NAME, deleteQuery, args);
}
}

View file

@ -21,7 +21,7 @@ import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.Objects;
@ -83,7 +83,7 @@ public class IdentityKeyMismatch {
public void serialize(IdentityKey value, JsonGenerator jsonGenerator, SerializerProvider serializers)
throws IOException
{
jsonGenerator.writeString(Base64.encodeBytes(value.serialize()));
jsonGenerator.writeString(Base64.encodeWithPadding(value.serialize()));
}
}

View file

@ -44,7 +44,7 @@ import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.DelimiterUtil;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
@ -379,8 +379,8 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
if (identityKey != null) {
MasterCipher masterCipher = new MasterCipher(masterSecret);
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
String macString = Base64.encodeBytes(masterCipher.getMacFor(recipientId +
String identityKeyString = Base64.encodeWithPadding(identityKey.serialize());
String macString = Base64.encodeWithPadding(masterCipher.getMacFor(recipientId +
identityKeyString));
db.execSQL("REPLACE INTO identities (recipient, key, mac) VALUES (?, ?, ?)",

View file

@ -19,7 +19,7 @@ import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.thoughtcrime.securesms.database.OneTimePreKeyTable;
import org.thoughtcrime.securesms.database.SignedPreKeyTable;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.JsonUtils;
import java.io.File;
@ -49,8 +49,8 @@ public final class PreKeyMigrationHelper {
ContentValues contentValues = new ContentValues();
contentValues.put(OneTimePreKeyTable.KEY_ID, preKey.getId());
contentValues.put(OneTimePreKeyTable.PUBLIC_KEY, Base64.encodeBytes(preKey.getKeyPair().getPublicKey().serialize()));
contentValues.put(OneTimePreKeyTable.PRIVATE_KEY, Base64.encodeBytes(preKey.getKeyPair().getPrivateKey().serialize()));
contentValues.put(OneTimePreKeyTable.PUBLIC_KEY, Base64.encodeWithPadding(preKey.getKeyPair().getPublicKey().serialize()));
contentValues.put(OneTimePreKeyTable.PRIVATE_KEY, Base64.encodeWithPadding(preKey.getKeyPair().getPrivateKey().serialize()));
database.insert(OneTimePreKeyTable.TABLE_NAME, null, contentValues);
Log.i(TAG, "Migrated one-time prekey: " + preKey.getId());
} catch (IOException | InvalidMessageException | InvalidKeyException e) {
@ -71,9 +71,9 @@ public final class PreKeyMigrationHelper {
ContentValues contentValues = new ContentValues();
contentValues.put(SignedPreKeyTable.KEY_ID, signedPreKey.getId());
contentValues.put(SignedPreKeyTable.PUBLIC_KEY, Base64.encodeBytes(signedPreKey.getKeyPair().getPublicKey().serialize()));
contentValues.put(SignedPreKeyTable.PRIVATE_KEY, Base64.encodeBytes(signedPreKey.getKeyPair().getPrivateKey().serialize()));
contentValues.put(SignedPreKeyTable.SIGNATURE, Base64.encodeBytes(signedPreKey.getSignature()));
contentValues.put(SignedPreKeyTable.PUBLIC_KEY, Base64.encodeWithPadding(signedPreKey.getKeyPair().getPublicKey().serialize()));
contentValues.put(SignedPreKeyTable.PRIVATE_KEY, Base64.encodeWithPadding(signedPreKey.getKeyPair().getPrivateKey().serialize()));
contentValues.put(SignedPreKeyTable.SIGNATURE, Base64.encodeWithPadding(signedPreKey.getSignature()));
contentValues.put(SignedPreKeyTable.TIMESTAMP, signedPreKey.getTimestamp());
database.insert(SignedPreKeyTable.TABLE_NAME, null, contentValues);
Log.i(TAG, "Migrated signed prekey: " + signedPreKey.getId());

View file

@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.jobs.UnableToStartException;
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob;
import org.thoughtcrime.securesms.service.GenericForegroundService;
import org.thoughtcrime.securesms.service.NotificationController;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.io.IOException;
@ -125,7 +125,7 @@ public class SQLCipherMigrationHelper {
plaintext = legacyCipher.decryptBytes(Base64.decode(mediaKey));
}
row.put("cd", Base64.encodeBytes(plaintext));
row.put("cd", Base64.encodeWithPadding(plaintext));
}
} catch (IOException | InvalidMessageException e) {
Log.w(TAG, e);

View file

@ -15,6 +15,7 @@ import android.text.TextUtils
import androidx.core.content.contentValuesOf
import com.annimon.stream.Stream
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.Hex
import org.signal.core.util.SqlUtil
@ -41,7 +42,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
import org.thoughtcrime.securesms.profiles.ProfileName
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FileUtils
import org.thoughtcrime.securesms.util.ServiceUtil
import org.thoughtcrime.securesms.util.Triple
@ -825,7 +825,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration {
val encodedProfileKey = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_key", null)
val profileKey = if (encodedProfileKey != null) Base64.decodeOrThrow(encodedProfileKey) else Util.getSecretBytes(32)
val values = ContentValues(1).apply {
put("profile_key", Base64.encodeBytes(profileKey))
put("profile_key", Base64.encodeWithPadding(profileKey))
}
if (db.update("recipient", values, "phone = ?", arrayOf(localNumber)) == 0) {
throw AssertionError("No rows updated!")
@ -851,7 +851,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration {
val id: String = cursor.getString(cursor.getColumnIndexOrThrow("_id"))
val values = ContentValues(2).apply {
put("dirty", 2)
put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey()))
put("storage_service_key", Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
db.update("recipient", values, "_id = ?", arrayOf(id))
}
@ -1434,7 +1434,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration {
insertCount = cursor.count
while (cursor.moveToNext()) {
val insertValues = ContentValues().apply {
put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey()))
put("storage_service_key", Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id"))
db.update("recipient", insertValues, "_id = ?", SqlUtil.buildArgs(id))
@ -1445,7 +1445,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration {
updateCount = cursor.count
while (cursor.moveToNext()) {
val updateValues = ContentValues().apply {
put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey()))
put("storage_service_key", Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
}
val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id"))
db.update("recipient", updateValues, "_id = ?", SqlUtil.buildArgs(id))
@ -2445,7 +2445,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration {
null,
contentValuesOf(
"distribution_list_id" to 1L,
"storage_service_key" to Base64.encodeBytes(StorageSyncHelper.generateKey()),
"storage_service_key" to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
"profile_sharing" to 1
)
)

View file

@ -4,11 +4,11 @@ import android.app.Application
import android.database.Cursor
import androidx.core.content.contentValuesOf
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
/**
* Performs a check and ensures that MyStory exists at the correct distribution list id and correct distribution id.
@ -87,7 +87,7 @@ object V151_MyStoryMigration : SignalDatabaseMigration {
contentValuesOf(
"group_type" to 4,
"distribution_list_id" to MY_STORY_DISTRIBUTION_LIST_ID,
"storage_service_key" to Base64.encodeBytes(StorageSyncHelper.generateKey()),
"storage_service_key" to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
"profile_sharing" to 1
)
)

View file

@ -4,11 +4,11 @@ import android.app.Application
import android.database.Cursor
import androidx.core.content.contentValuesOf
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
/**
* Performs a check and ensures that MyStory exists at the correct distribution list id and correct distribution id.
@ -87,7 +87,7 @@ object V153_MyStoryMigration : SignalDatabaseMigration {
contentValuesOf(
"group_type" to 4,
"distribution_list_id" to MY_STORY_DISTRIBUTION_LIST_ID,
"storage_service_key" to Base64.encodeBytes(StorageSyncHelper.generateKey()),
"storage_service_key" to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
"profile_sharing" to 1
)
)

View file

@ -18,7 +18,7 @@ import org.signal.libsignal.protocol.util.ByteUtil;
import org.thoughtcrime.securesms.devicelist.Device;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.AsyncLoader;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;

View file

@ -1,11 +1,11 @@
package org.thoughtcrime.securesms.database.model
import org.signal.core.util.Base64
import org.signal.core.util.StringSerializer
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.util.Base64
object BodyRangeListSerializer : StringSerializer<BodyRangeList> {
override fun serialize(data: BodyRangeList): String = Base64.encodeBytes(data.encode())
override fun serialize(data: BodyRangeList): String = Base64.encodeWithPadding(data.encode())
override fun deserialize(data: String): BodyRangeList = BodyRangeList.ADAPTER.decode(Base64.decode(data))
}

View file

@ -5,7 +5,7 @@ import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.model.databaseprotos.GroupCallUpdateDetails;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.List;
@ -38,6 +38,6 @@ public final class GroupCallUpdateDetailsUtil {
.isCallFull(isCallFull)
.inCallUuids(inCallUuids);
return Base64.encodeBytes(builder.build().encode());
return Base64.encodeWithPadding(builder.build().encode());
}
}

View file

@ -56,7 +56,7 @@ import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
@ -508,7 +508,7 @@ public abstract class MessageRecord extends DisplayRecord {
List<ByteString> deleteRequestingMembers = new ArrayList<>(change.deleteRequestingMembers);
deleteRequestingMembers.add(id);
return Base64.encodeBytes(decryptedGroupV2Context.newBuilder()
return Base64.encodeWithPadding(decryptedGroupV2Context.newBuilder()
.change(change.newBuilder()
.revision(revision)
.deleteRequestingMembers(deleteRequestingMembers)

View file

@ -3,11 +3,11 @@ package org.thoughtcrime.securesms.groups.v2;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.Base64;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
import org.signal.storageservice.protos.groups.GroupInviteLink;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException;
import java.net.URI;
@ -58,7 +58,7 @@ public final class GroupInviteLinkUrl {
throw new InvalidGroupLinkException("No reference was in the uri");
}
byte[] bytes = Base64UrlSafe.decodePaddingAgnostic(encoding);
byte[] bytes = Base64.decode(encoding);
GroupInviteLink groupInviteLink = GroupInviteLink.ADAPTER.decode(bytes);
//noinspection SwitchStatementWithTooFewBranches
@ -112,7 +112,7 @@ public final class GroupInviteLinkUrl {
.build())
.build();
String encoding = Base64UrlSafe.encodeBytesWithoutPadding(groupInviteLink.encode());
String encoding = Base64.encodeUrlSafeWithoutPadding(groupInviteLink.encode());
return GROUP_URL_PREFIX + encoding;
}

View file

@ -6,7 +6,7 @@ import androidx.annotation.Nullable;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.JsonUtils;
import java.io.IOException;
@ -427,7 +427,7 @@ public class JsonJobData {
}
public Builder putBlobAsString(@NonNull String key, @Nullable byte[] value) {
String serialized = value != null ? Base64.encodeBytes(value) : null;
String serialized = value != null ? Base64.encodeWithPadding(value) : null;
strings.put(key, serialized);
return this;
}

View file

@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.jobmanager.migrations
import okio.ByteString.Companion.toByteString
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.jobmanager.JobMigration
import org.thoughtcrime.securesms.jobmanager.JsonJobData
import org.thoughtcrime.securesms.jobs.FailingJob
import org.thoughtcrime.securesms.jobs.PushProcessMessageErrorJob
import org.thoughtcrime.securesms.messages.MessageState
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.crypto.protos.CompleteMessage
import org.whispersystems.signalservice.api.crypto.protos.EnvelopeMetadata
import org.whispersystems.signalservice.api.push.ServiceId

View file

@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.jobmanager.JobMigration;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto;

View file

@ -1,12 +1,12 @@
package org.thoughtcrime.securesms.jobs
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.ProfileUtil
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
import java.io.IOException
@ -57,7 +57,7 @@ class AccountConsistencyWorkerJob private constructor(parameters: Parameters) :
}
val profile: SignalServiceProfile = ProfileUtil.retrieveProfileSync(context, Recipient.self(), SignalServiceProfile.RequestType.PROFILE, false).profile
val encodedPublicKey = Base64.encodeBytes(SignalStore.account().aciIdentityKey.publicKey.serialize())
val encodedPublicKey = Base64.encodeWithPadding(SignalStore.account().aciIdentityKey.publicKey.serialize())
if (profile.identityKey != encodedPublicKey) {
Log.w(TAG, "Identity key on profile differed from the one we have locally! Marking ourselves unregistered.")

View file

@ -34,7 +34,7 @@ import org.thoughtcrime.securesms.releasechannel.ReleaseChannel;
import org.thoughtcrime.securesms.s3.S3;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.AttachmentUtil;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;

View file

@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@ -46,7 +46,7 @@ public class MmsReceiveJob extends BaseJob {
@Override
public @Nullable byte[] serialize() {
return new JsonJobData.Builder().putString(KEY_DATA, Base64.encodeBytes(data))
return new JsonJobData.Builder().putString(KEY_DATA, Base64.encodeWithPadding(data))
.putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
.serialize();
}

View file

@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@ -76,7 +76,7 @@ public class MultiDeviceVerifiedUpdateJob extends BaseJob {
@Override
public @Nullable byte[] serialize() {
return new JsonJobData.Builder().putString(KEY_DESTINATION, destination.serialize())
.putString(KEY_IDENTITY_KEY, Base64.encodeBytes(identityKey))
.putString(KEY_IDENTITY_KEY, Base64.encodeWithPadding(identityKey))
.putInt(KEY_VERIFIED_STATUS, verifiedStatus.toInt())
.putLong(KEY_TIMESTAMP, timestamp)
.serialize();

View file

@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.signalservice.api.crypto.ContentHint;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@ -120,7 +120,7 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
return new JsonJobData.Builder().putString(KEY_RECIPIENTS, RecipientId.toSerializedList(recipients))
.putInt(KEY_INITIAL_RECIPIENT_COUNT, initialRecipientCount)
.putLong(KEY_TIMESTAMP, timestamp)
.putString(KEY_GROUP_CONTEXT_V2, Base64.encodeBytes(groupContextV2.encode()))
.putString(KEY_GROUP_CONTEXT_V2, Base64.encodeWithPadding(groupContextV2.encode()))
.serialize();
}

View file

@ -60,7 +60,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.ImageCompressionUtil;

View file

@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.account.AccountAttributes;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureException;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -118,7 +118,7 @@ public class RefreshAttributesJob extends BaseJob {
universalUnidentifiedAccess,
capabilities,
phoneNumberDiscoverable,
(encryptedDeviceName == null) ? null : Base64.encodeBytes(encryptedDeviceName),
(encryptedDeviceName == null) ? null : Base64.encodeWithPadding(encryptedDeviceName),
pniRegistrationId,
recoveryPassword
);

View file

@ -5,6 +5,7 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.usernames.BaseUsernameException;
import org.signal.libsignal.usernames.Username;
@ -23,7 +24,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.subscription.Subscriber;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.ProfileUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@ -38,7 +38,6 @@ import org.whispersystems.signalservice.api.util.ExpiringProfileCredentialUtil;
import org.whispersystems.signalservice.internal.ServiceResponse;
import org.whispersystems.signalservice.internal.push.ReserveUsernameResponse;
import org.whispersystems.signalservice.internal.push.WhoAmIResponse;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException;
import java.util.Collections;
@ -273,7 +272,7 @@ public class RefreshOwnProfileJob extends BaseJob {
WhoAmIResponse whoAmIResponse = ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI();
boolean hasServerUsername = !TextUtils.isEmpty(whoAmIResponse.getUsernameHash());
String serverUsernameHash = whoAmIResponse.getUsernameHash();
String localUsernameHash = Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(localUsername));
String localUsernameHash = Base64.encodeUrlSafeWithoutPadding(Username.hash(localUsername));
if (!hasServerUsername) {
Log.w(TAG, "No remote username is set.");

View file

@ -13,7 +13,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
@ -86,7 +86,7 @@ public class ReportSpamJob extends BaseJob {
byte[] reportingTokenBytes = SignalDatabase.recipients().getReportingToken(recipientId);
if (reportingTokenBytes != null) {
reportingTokenEncoded = Base64.encodeBytes(reportingTokenBytes);
reportingTokenEncoded = Base64.encodeWithPadding(reportingTokenBytes);
}
signalServiceAccountManager.reportSpam(serviceId.get(), data.getServerGuid(), reportingTokenEncoded);

View file

@ -40,7 +40,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.IdentityUtil;
import org.thoughtcrime.securesms.util.ProfileUtil;
import org.thoughtcrime.securesms.util.Util;

View file

@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.VerificationCodeParser;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@ -74,7 +74,7 @@ public class SmsReceiveJob extends BaseJob {
public @Nullable byte[] serialize() {
String[] encoded = new String[pdus.length];
for (int i = 0; i < pdus.length; i++) {
encoded[i] = Base64.encodeBytes((byte[]) pdus[i]);
encoded[i] = Base64.encodeWithPadding((byte[]) pdus[i]);
}
return new JsonJobData.Builder().putStringArray(KEY_PDUS, encoded)

View file

@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.subscription.Subscriber;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription;
import org.whispersystems.signalservice.api.subscriptions.SubscriberId;
import org.whispersystems.signalservice.internal.ServiceResponse;

View file

@ -5,6 +5,7 @@ import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import androidx.annotation.VisibleForTesting
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.IdentityKey
import org.signal.libsignal.protocol.IdentityKeyPair
@ -19,7 +20,6 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.api.push.ServiceId.ACI

View file

@ -6,7 +6,7 @@ import android.os.Build;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.KeyStoreHelper;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.io.IOException;
@ -49,7 +49,7 @@ public class LogSecretProvider {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret);
TextSecurePreferences.setLogEncryptedSecret(context, encryptedSecret.serialize());
} else {
TextSecurePreferences.setLogUnencryptedSecret(context, Base64.encodeBytes(secret));
TextSecurePreferences.setLogUnencryptedSecret(context, Base64.encodeWithPadding(secret));
}
return secret;

View file

@ -4,6 +4,7 @@ import android.graphics.Bitmap
import android.net.Uri
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.Base64
import org.signal.core.util.ThreadUtil
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
@ -20,7 +21,6 @@ import org.thoughtcrime.securesms.mms.OutgoingMessage
import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.Base64
import java.io.ByteArrayOutputStream
private val TAG = Log.tag(TextStoryPostSendRepository::class.java)
@ -110,6 +110,6 @@ class TextStoryPostSendRepository {
builder.textBackgroundColor = textStoryPostCreationState.textBackgroundColor
builder.textForegroundColor = textStoryPostCreationState.textForegroundColor
return Base64.encodeBytes(builder.build().encode())
return Base64.encodeWithPadding(builder.build().encode())
}
}

View file

@ -5,6 +5,7 @@ import android.content.Context
import android.text.TextUtils
import com.mobilecoin.lib.exceptions.SerializationException
import okio.ByteString.Companion.toByteString
import org.signal.core.util.Base64
import org.signal.core.util.Hex
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
@ -88,7 +89,6 @@ import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage
import org.thoughtcrime.securesms.sms.IncomingTextMessage
import org.thoughtcrime.securesms.stickers.StickerLocator
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.EarlyMessageCacheEntry
import org.thoughtcrime.securesms.util.LinkUtil
import org.thoughtcrime.securesms.util.MediaUtil
@ -825,7 +825,7 @@ object DataMessageProcessor {
receivedTimeMillis = receivedTime,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
body = Base64.encodeBytes(dbGiftBadge.encode()),
body = Base64.encodeWithPadding(dbGiftBadge.encode()),
serverGuid = envelope.serverGuid,
giftBadge = dbGiftBadge
)

View file

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.messages
import android.graphics.Color
import org.signal.core.util.Base64
import org.signal.core.util.orNull
import org.thoughtcrime.securesms.database.MessageTable.InsertResult
import org.thoughtcrime.securesms.database.SignalDatabase
@ -17,7 +18,6 @@ import org.thoughtcrime.securesms.mms.IncomingMediaMessage
import org.thoughtcrime.securesms.mms.MmsException
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.FeatureFlags
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.internal.push.Content
@ -147,6 +147,6 @@ object StoryMessageProcessor {
}
builder.background(chatColorBuilder.build())
return Base64.encodeBytes(builder.build().encode())
return Base64.encodeWithPadding(builder.build().encode())
}
}

View file

@ -1,8 +1,8 @@
package org.thoughtcrime.securesms.messages
import org.signal.core.util.Base64
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
import org.thoughtcrime.securesms.mms.OutgoingMessage
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.messages.SignalServicePreview
import org.whispersystems.signalservice.api.messages.SignalServiceTextAttachment
import java.io.IOException

View file

@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2
import org.thoughtcrime.securesms.messages.SignalServiceProtoUtil;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
@ -51,14 +51,14 @@ public final class MessageGroupContext {
}
public MessageGroupContext(@NonNull GroupContext group) {
this.encodedGroupContext = Base64.encodeBytes(group.encode());
this.encodedGroupContext = Base64.encodeWithPadding(group.encode());
this.groupV1 = new GroupV1Properties(group);
this.groupV2 = null;
this.group = groupV1;
}
public MessageGroupContext(@NonNull DecryptedGroupV2Context group) {
this.encodedGroupContext = Base64.encodeBytes(group.encode());
this.encodedGroupContext = Base64.encodeWithPadding(group.encode());
this.groupV1 = null;
this.groupV2 = new GroupV2Properties(group);
this.group = groupV2;

View file

@ -9,7 +9,7 @@ import com.mobilecoin.lib.Verifier;
import com.mobilecoin.lib.exceptions.AttestationException;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.internal.push.AuthCredentials;

View file

@ -8,7 +8,7 @@ import com.mobilecoin.lib.ClientConfig;
import com.mobilecoin.lib.exceptions.AttestationException;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.internal.push.AuthCredentials;

View file

@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.profiles.manage
import androidx.annotation.WorkerThread
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.Base64
import org.signal.core.util.Result
import org.signal.core.util.Result.Companion.failure
import org.signal.core.util.Result.Companion.success
@ -24,7 +25,6 @@ import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulRespons
import org.whispersystems.signalservice.api.push.exceptions.UsernameIsNotReservedException
import org.whispersystems.signalservice.api.push.exceptions.UsernameMalformedException
import org.whispersystems.signalservice.api.push.exceptions.UsernameTakenException
import org.whispersystems.util.Base64UrlSafe
import java.io.IOException
/**
@ -153,7 +153,7 @@ class UsernameRepository {
val candidates: List<Username> = Username.candidatesFrom(nickname, UsernameUtil.MIN_LENGTH, UsernameUtil.MAX_LENGTH)
val hashes: List<String> = candidates
.map { Base64UrlSafe.encodeBytesWithoutPadding(it.hash) }
.map { Base64.encodeUrlSafeWithoutPadding(it.hash) }
val response = accountManager.reserveUsername(hashes)

View file

@ -8,6 +8,7 @@ import androidx.core.app.ShareCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.setFragmentResult
import androidx.navigation.fragment.findNavController
import org.signal.core.util.Base64
import org.signal.core.util.DimensionUnit
import org.signal.core.util.concurrent.LifecycleDisposable
import org.signal.libsignal.usernames.Username
@ -20,7 +21,6 @@ import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.FragmentResultContract
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.util.Base64UrlSafe
/**
* Allows the user to either share their username directly or to copy it to their clipboard.
@ -71,7 +71,7 @@ class UsernameShareBottomSheet : DSLSettingsBottomSheetFragment() {
customPref(
CopyButton.Model(
text = getString(R.string.signal_me_username_url, Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))),
text = getString(R.string.signal_me_username_url, Base64.encodeUrlSafeWithoutPadding(Username.hash(username))),
onClick = {
copyToClipboard(it)
}
@ -82,7 +82,7 @@ class UsernameShareBottomSheet : DSLSettingsBottomSheetFragment() {
customPref(
ShareButton.Model(
text = getString(R.string.signal_me_username_url, Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))),
text = getString(R.string.signal_me_username_url, Base64.encodeUrlSafeWithoutPadding(Username.hash(username))),
onClick = {
openShareSheet(it.text)
}

View file

@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.util.Collections;

View file

@ -7,6 +7,7 @@ import okhttp3.ConnectionSpec
import okhttp3.Dns
import okhttp3.Interceptor
import okhttp3.TlsVersion
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.keyvalue.SettingsValues
@ -18,7 +19,6 @@ import org.thoughtcrime.securesms.net.RemoteDeprecationDetectorInterceptor
import org.thoughtcrime.securesms.net.SequentialDns
import org.thoughtcrime.securesms.net.StandardUserAgentInterceptor
import org.thoughtcrime.securesms.net.StaticDns
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.push.TrustStore
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl
import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl

View file

@ -35,7 +35,7 @@ import org.whispersystems.signalservice.api.push.exceptions.IncorrectCodeExcepti
import org.whispersystems.signalservice.api.push.exceptions.IncorrectRegistrationRecoveryPasswordException;
import org.whispersystems.signalservice.internal.ServiceResponse;
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataResponse;
import org.whispersystems.util.Base64;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

View file

@ -9,9 +9,9 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import okio.ByteString
import okio.ByteString.Companion.toByteString
import org.signal.core.util.Base64
import org.signal.core.util.Serializer
import org.signal.ringrtc.CallLinkRootKey
import org.thoughtcrime.securesms.util.Base64
@Parcelize
class CallLinkRoomId private constructor(private val roomId: ByteArray) : Parcelable {
@ -40,7 +40,7 @@ class CallLinkRoomId private constructor(private val roomId: ByteArray) : Parcel
object DatabaseSerializer : Serializer<CallLinkRoomId, String> {
override fun serialize(data: CallLinkRoomId): String {
return Base64.encodeBytes(data.roomId)
return Base64.encodeWithPadding(data.roomId)
}
override fun deserialize(data: String): CallLinkRoomId {

View file

@ -46,7 +46,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.MessageSender.SendType;
import org.thoughtcrime.securesms.stories.Stories;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.MessageUtil;
import org.thoughtcrime.securesms.util.Util;
@ -390,7 +390,7 @@ public final class MultiShareSender {
{
return OutgoingMessage.textStoryMessage(
recipient,
Base64.encodeBytes(new StoryTextPost.Builder()
Base64.encodeWithPadding(new StoryTextPost.Builder()
.body(getBodyForTextStory(multiShareArgs.getDraftText(), multiShareArgs.getLinkPreview()))
.style(StoryTextPost.Style.DEFAULT)
.background(background.serialize())

View file

@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.payments.Entropy;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.subscription.Subscriber;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.push.UsernameLinkComponents;
@ -69,8 +69,8 @@ public final class StorageSyncHelper {
public static @NonNull IdDifferenceResult findIdDifference(@NonNull Collection<StorageId> remoteIds,
@NonNull Collection<StorageId> localIds)
{
Map<String, StorageId> remoteByRawId = Stream.of(remoteIds).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> localByRawId = Stream.of(localIds).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> remoteByRawId = Stream.of(remoteIds).collect(Collectors.toMap(id -> Base64.encodeWithPadding(id.getRaw()), id -> id));
Map<String, StorageId> localByRawId = Stream.of(localIds).collect(Collectors.toMap(id -> Base64.encodeWithPadding(id.getRaw()), id -> id));
boolean hasTypeMismatch = remoteByRawId.size() != remoteIds.size() || localByRawId.size() != localIds.size();

View file

@ -7,7 +7,7 @@ import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.signal.core.util.SetUtil;
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
@ -34,10 +34,10 @@ public final class StorageSyncValidations {
validateManifestAndInserts(result.getManifest(), result.getInserts(), self);
if (result.getDeletes().size() > 0) {
Set<String> allSetEncoded = Stream.of(result.getManifest().getStorageIds()).map(StorageId::getRaw).map(Base64::encodeBytes).collect(Collectors.toSet());
Set<String> allSetEncoded = Stream.of(result.getManifest().getStorageIds()).map(StorageId::getRaw).map(Base64::encodeWithPadding).collect(Collectors.toSet());
for (byte[] delete : result.getDeletes()) {
String encoded = Base64.encodeBytes(delete);
String encoded = Base64.encodeWithPadding(delete);
if (allSetEncoded.contains(encoded)) {
throw new DeletePresentInFullIdSetError();
}

View file

@ -15,6 +15,7 @@ import com.bumptech.glide.load.Options
import com.bumptech.glide.load.ResourceDecoder
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.SimpleResource
import org.signal.core.util.Base64
import org.signal.core.util.concurrent.safeBlockingGet
import org.signal.core.util.readParcelableCompat
import org.thoughtcrime.securesms.R
@ -32,7 +33,6 @@ import org.thoughtcrime.securesms.fonts.TypefaceCache
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.ParcelUtil
import java.io.IOException
import java.security.MessageDigest

View file

@ -12,6 +12,7 @@ import androidx.core.app.ShareCompat
import androidx.fragment.app.Fragment
import com.bumptech.glide.load.Options
import io.reactivex.rxjava3.core.Single
import org.signal.core.util.Base64
import org.signal.core.util.DimensionUnit
import org.signal.core.util.concurrent.SimpleTask
import org.signal.core.util.logging.Log
@ -27,7 +28,6 @@ import org.thoughtcrime.securesms.stories.StoryTextPostModel
import org.thoughtcrime.securesms.stories.landing.StoriesLandingItem
import org.thoughtcrime.securesms.stories.viewer.page.StoryPost
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageState
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.BitmapUtil
import org.thoughtcrime.securesms.util.DeleteDialog
import org.thoughtcrime.securesms.util.MediaUtil

View file

@ -6,6 +6,7 @@ import androidx.annotation.CheckResult
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.Base64
import org.signal.core.util.BreakIteratorCompat
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
@ -26,7 +27,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.Base64
/**
* Open for testing.

View file

@ -8,10 +8,10 @@ import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
import org.thoughtcrime.securesms.stories.viewer.page.StoryPost
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.rx.RxStore
import kotlin.time.Duration
import kotlin.time.Duration.Companion.microseconds

View file

@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories.viewer.post
import android.graphics.Typeface
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.Base64
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
@ -10,7 +11,6 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.fonts.TextFont
import org.thoughtcrime.securesms.fonts.TextToScript
import org.thoughtcrime.securesms.fonts.TypefaceCache
import org.thoughtcrime.securesms.util.Base64
class StoryTextPostRepository {
fun getRecord(recordId: Long): Single<MmsMessageRecord> {

View file

@ -8,6 +8,7 @@ import android.content.pm.Signature;
import androidx.annotation.NonNull;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import java.nio.charset.StandardCharsets;
@ -56,7 +57,7 @@ public final class AppSignatureUtil {
byte[] hashSignature = messageDigest.digest();
hashSignature = Arrays.copyOfRange(hashSignature, 0, HASH_LENGTH_BYTES);
String base64Hash = Base64.encodeBytes(hashSignature);
String base64Hash = Base64.encodeWithPadding(hashSignature);
base64Hash = base64Hash.substring(0, HASH_LENGTH_CHARS);
return base64Hash;

View file

@ -1,48 +0,0 @@
package org.thoughtcrime.securesms.util;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.IOException;
public final class Base64 {
private Base64() {
}
public static @NonNull byte[] decode(@NonNull String s) throws IOException {
return org.whispersystems.util.Base64.decode(s);
}
public static @NonNull byte[] decodeWithoutPadding(@NonNull String s) throws IOException {
return org.whispersystems.util.Base64.decodeWithoutPadding(s);
}
public static @NonNull String encodeBytes(@NonNull byte[] source) {
return org.whispersystems.util.Base64.encodeBytes(source);
}
public static @NonNull String encodeBytesWithoutPadding(@NonNull byte[] source) {
return org.whispersystems.util.Base64.encodeBytesWithoutPadding(source);
}
public static @NonNull byte[] decodeOrThrow(@NonNull String s) {
try {
return org.whispersystems.util.Base64.decode(s);
} catch (IOException e) {
throw new AssertionError();
}
}
public static @Nullable byte[] decodeNullableOrThrow(@Nullable String s) {
if (s == null) {
return null;
}
try {
return org.whispersystems.util.Base64.decode(s);
} catch (IOException e) {
throw new AssertionError();
}
}
}

View file

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.IdentityKeyPair;

View file

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.util
import androidx.annotation.WorkerThread
import org.signal.core.util.Base64
import org.signal.core.util.logging.Log
import org.signal.libsignal.usernames.BaseUsernameException
import org.signal.libsignal.usernames.Username
@ -11,7 +12,6 @@ import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.UsernameLinkComponents
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.api.util.toByteArray
import org.whispersystems.util.Base64UrlSafe
import java.io.IOException
import java.util.Locale
import java.util.Optional
@ -85,7 +85,7 @@ object UsernameUtil {
Log.d(TAG, "No local user with this username. Searching remotely.")
return try {
fetchAciForUsernameHash(Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username)))
fetchAciForUsernameHash(Base64.encodeUrlSafeWithoutPadding(Username.hash(username)))
} catch (e: BaseUsernameException) {
Optional.empty()
}
@ -97,7 +97,7 @@ object UsernameUtil {
*/
@Throws(BaseUsernameException::class)
fun hashUsernameToBase64(username: String?): String {
return Base64UrlSafe.encodeBytesWithoutPadding(Username.hash(username))
return Base64.encodeUrlSafeWithoutPadding(Username.hash(username))
}
@JvmStatic
@ -117,7 +117,7 @@ object UsernameUtil {
*/
fun generateLink(components: UsernameLinkComponents): String {
val combined: ByteArray = components.entropy + components.serverId.toByteArray()
val base64 = Base64UrlSafe.encodeBytesWithoutPadding(combined)
val base64 = Base64.encodeUrlSafeWithoutPadding(combined)
return BASE_URL + base64
}
@ -128,7 +128,7 @@ object UsernameUtil {
fun parseLink(url: String): UsernameLinkComponents? {
val match: MatchResult = URL_PATTERN.find(url) ?: return null
val path: String = match.groups[2]?.value ?: return null
val allBytes: ByteArray = Base64UrlSafe.decodePaddingAgnostic(path)
val allBytes: ByteArray = Base64.decode(path)
if (allBytes.size != 48) {
return null

View file

@ -44,6 +44,7 @@ import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.R;
@ -359,7 +360,7 @@ public class Util {
public static String getSecret(int size) {
byte[] secret = getSecretBytes(size);
return Base64.encodeBytes(secret);
return Base64.encodeWithPadding(secret);
}
public static byte[] getSecretBytes(int size) {

View file

@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.mms.PartUriParser;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.Base64;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream;

View file

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.database
import android.database.Cursor
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.requireLong
import org.signal.spinner.ColumnTransformer
@ -9,7 +10,6 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.UpdateDescription
import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.util.Base64
object GV2UpdateTransformer : ColumnTransformer {
override fun matches(tableName: String?, columnName: String): Boolean {

View file

@ -6,10 +6,10 @@
package org.thoughtcrime.securesms.database
import android.database.Cursor
import org.signal.core.util.Base64
import org.signal.core.util.requireBlob
import org.signal.libsignal.protocol.state.KyberPreKeyRecord
import org.signal.spinner.ColumnTransformer
import org.thoughtcrime.securesms.util.Base64
object KyberKeyTransformer : ColumnTransformer {
override fun matches(tableName: String?, columnName: String): Boolean {
@ -18,6 +18,6 @@ object KyberKeyTransformer : ColumnTransformer {
override fun transform(tableName: String?, columnName: String, cursor: Cursor): String? {
val record = KyberPreKeyRecord(cursor.requireBlob(columnName))
return "ID: ${record.id}\nTimestamp: ${record.timestamp}\nPublicKey: ${Base64.encodeBytesWithoutPadding(record.keyPair.publicKey.serialize())}\nPrivateKey: ${Base64.encodeBytesWithoutPadding(record.keyPair.secretKey.serialize())}\nSignature: ${Base64.encodeBytesWithoutPadding(record.signature)}"
return "ID: ${record.id}\nTimestamp: ${record.timestamp}\nPublicKey: ${Base64.encodeWithoutPadding(record.keyPair.publicKey.serialize())}\nPrivateKey: ${Base64.encodeWithoutPadding(record.keyPair.secretKey.serialize())}\nSignature: ${Base64.encodeWithoutPadding(record.signature)}"
}
}

View file

@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.database
import android.database.Cursor
import org.signal.core.util.Base64
import org.signal.core.util.Hex
import org.signal.core.util.requireString
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential
import org.signal.spinner.ColumnTransformer
import org.signal.spinner.DefaultColumnTransformer
import org.thoughtcrime.securesms.database.model.databaseprotos.ExpiringProfileKeyCredentialColumnData
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.toLocalDateTime
import java.security.MessageDigest
@ -27,7 +27,7 @@ object ProfileKeyCredentialTransformer : ColumnTransformer {
Expires: ${credential.expirationTime.toLocalDateTime()}
Matching Profile Key:
${Base64.encodeBytes(columnData.profileKey.toByteArray())}
${Base64.encodeWithPadding(columnData.profileKey.toByteArray())}
""".trimIndent().replace("\n", "<br>")
}
}

View file

@ -7,9 +7,9 @@ import org.hamcrest.Matchers.`is`
import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.signal.core.util.Base64
import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context
import org.thoughtcrime.securesms.groups.v2.ChangeBuilder
import org.thoughtcrime.securesms.util.Base64
import org.whispersystems.signalservice.api.push.ServiceId.ACI
import org.whispersystems.signalservice.internal.push.GroupContextV2
import java.util.Random

View file

@ -3,10 +3,10 @@ package org.thoughtcrime.securesms.groups.v2;
import androidx.annotation.NonNull;
import org.junit.Test;
import org.signal.core.util.Base64;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.storageservice.protos.groups.GroupInviteLink;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException;
@ -98,13 +98,13 @@ public final class GroupInviteLinkUrl_InvalidGroupLinkException_Test {
private static String createEncodedProtobuf(@NonNull byte[] groupMasterKey,
@NonNull byte[] passwordBytes)
{
return Base64UrlSafe.encodeBytesWithoutPadding(new GroupInviteLink.Builder()
.v1Contents(new GroupInviteLink.GroupInviteLinkContentsV1.Builder()
.groupMasterKey(ByteString.of(groupMasterKey))
.inviteLinkPassword(ByteString.of(passwordBytes))
.build())
.build()
.encode());
return Base64.encodeUrlSafeWithoutPadding(new GroupInviteLink.Builder()
.v1Contents(new GroupInviteLink.GroupInviteLinkContentsV1.Builder()
.groupMasterKey(ByteString.of(groupMasterKey))
.inviteLinkPassword(ByteString.of(passwordBytes))
.build())
.build()
.encode());
}
}

View file

@ -16,6 +16,7 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.signal.core.util.Base64
import org.signal.core.util.getParcelableExtraCompat
import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.database.FakeMessageRecords
@ -26,7 +27,6 @@ import org.thoughtcrime.securesms.mms.ImageSlide
import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.util.MediaUtil
import org.whispersystems.util.Base64
import java.util.Optional
@RunWith(RobolectricTestRunner::class)
@ -74,7 +74,7 @@ class StoryContextMenuTest {
val expected = "Hello"
val storyRecord = FakeMessageRecords.buildMediaMmsMessageRecord(
storyType = StoryType.TEXT_STORY_WITH_REPLIES,
body = Base64.encodeBytes(StoryTextPost.Builder().body(expected).build().encode())
body = Base64.encodeWithPadding(StoryTextPost.Builder().body(expected).build().encode())
)
// WHEN
@ -93,7 +93,7 @@ class StoryContextMenuTest {
val expected = "https://www.signal.org"
val storyRecord = FakeMessageRecords.buildMediaMmsMessageRecord(
storyType = StoryType.TEXT_STORY_WITH_REPLIES,
body = Base64.encodeBytes(StoryTextPost.Builder().build().encode()),
body = Base64.encodeWithPadding(StoryTextPost.Builder().build().encode()),
linkPreviews = listOf(LinkPreview(expected, "", "", 0L, Optional.empty()))
)
@ -115,7 +115,7 @@ class StoryContextMenuTest {
val expected = "$text $url"
val storyRecord = FakeMessageRecords.buildMediaMmsMessageRecord(
storyType = StoryType.TEXT_STORY_WITH_REPLIES,
body = Base64.encodeBytes(StoryTextPost.Builder().body(text).build().encode()),
body = Base64.encodeWithPadding(StoryTextPost.Builder().body(text).build().encode()),
linkPreviews = listOf(LinkPreview(url, "", "", 0L, Optional.empty()))
)

View file

@ -0,0 +1,116 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.core.util
import java.io.IOException
import java.io.UnsupportedEncodingException
object Base64 {
/**
* Encodes the bytes as a normal Base64 string with padding. Not URL safe. For url-safe, use [encodeUrlSafe].
*
* Note: the [offset] and [length] are there to support a legacy usecase, which is why they're not present on
* the other encode* methods.
*/
@JvmOverloads
@JvmStatic
fun encodeWithPadding(bytes: ByteArray, offset: Int = 0, length: Int = bytes.size): String {
return Base64Tools.encodeBytes(bytes, offset, length)
}
/**
* Encodes the bytes as a normal Base64 string without padding. Not URL safe. For url-safe, use [encodeUrlSafe].
*/
@JvmStatic
fun encodeWithoutPadding(bytes: ByteArray): String {
return Base64Tools.encodeBytes(bytes).stripPadding()
}
/**
* Encodes the bytes as a url-safe Base64 string with padding. It basically replaces the '+' and '/' characters in the
* normal encoding scheme with '-' and '_'.
*/
@JvmStatic
fun encodeUrlSafeWithPadding(bytes: ByteArray): String {
return Base64Tools.encodeBytes(bytes, Base64Tools.URL_SAFE or Base64Tools.DONT_GUNZIP)
}
/**
* Encodes the bytes as a url-safe Base64 string without padding. It basically replaces the '+' and '/' characters in the
* normal encoding scheme with '-' and '_'.
*/
@JvmStatic
fun encodeUrlSafeWithoutPadding(bytes: ByteArray): String {
return Base64Tools.encodeBytes(bytes, Base64Tools.URL_SAFE or Base64Tools.DONT_GUNZIP).stripPadding()
}
/**
* A very lenient decoder. Does not care about the presence of padding or whether it's url-safe or not. It'll just decode it.
*/
@Throws(IOException::class)
@JvmStatic
fun decode(value: String): ByteArray {
return if (value.contains('-') || value.contains('_')) {
Base64Tools.decode(value.withPaddingIfNeeded(), Base64Tools.URL_SAFE or Base64Tools.DONT_GUNZIP)
} else {
Base64Tools.decode(value.withPaddingIfNeeded())
}
}
@JvmStatic
fun decode(value: ByteArray): ByteArray {
// This pattern of trying US_ASCII first mimics how Base64Tools handles strings
return try {
decode(String(value, Charsets.US_ASCII))
} catch (e: UnsupportedEncodingException) {
decode(String(value, Charsets.UTF_8))
}
}
/**
* The same as [decode], except that instead of requiring you to handle an exception, this will just crash on invalid base64 strings.
* Should only be used if the value is definitely a valid base64 string.
*/
@JvmStatic
fun decodeOrThrow(value: String): ByteArray {
return try {
decode(value)
} catch (e: IOException) {
throw AssertionError(e)
}
}
/**
* The same as [decode], except that instead of requiring you to handle an exception, this will just crash on invalid base64 strings.
* It also allows null inputs. If the input is null, the outpul will be null.
* Should only be used if the value is definitely a valid base64 string.
*/
@JvmStatic
fun decodeNullableOrThrow(value: String?): ByteArray? {
if (value == null) {
return null
}
return try {
decode(value)
} catch (e: IOException) {
throw AssertionError(e)
}
}
private fun String.withPaddingIfNeeded(): String {
return when (this.length % 4) {
2 -> "$this=="
3 -> "$this="
else -> this
}
}
private fun String.stripPadding(): String {
return this.replace("=", "")
}
}

View file

@ -1,4 +1,4 @@
package org.whispersystems.util;
package org.signal.core.util;
/**
* <p>Encodes and decodes to and from Base64 notation.</p>
@ -6,9 +6,9 @@ package org.whispersystems.util;
*
* <p>Example:</p>
*
* <code>String encoded = Base64.encode( myByteArray );</code>
* <code>String encoded = Base64Tools.encode( myByteArray );</code>
* <br />
* <code>byte[] myByteArray = Base64.decode( encoded );</code>
* <code>byte[] myByteArray = Base64Tools.decode( encoded );</code>
*
* <p>The <tt>options</tt> parameter, which appears in a few places, is used to pass
* several pieces of information to the encoder. In the "higher level" methods such as
@ -24,10 +24,10 @@ package org.whispersystems.util;
* <p>The constants defined in Base64 can be OR-ed together to combine options, so you
* might make a call like this:</p>
*
* <code>String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES );</code>
* <code>String encoded = Base64Tools.encodeBytes( mybytes, Base64Tools.GZIP | Base64Tools.DO_BREAK_LINES );</code>
* <p>to compress the data before encoding it and then making the output have newline characters.</p>
* <p>Also...</p>
* <code>String encoded = Base64.encodeBytes( crazyString.getBytes() );</code>
* <code>String encoded = Base64Tools.encodeBytes( crazyString.getBytes() );</code>
*
*
*
@ -36,11 +36,11 @@ package org.whispersystems.util;
* </p>
* <ul>
* <li>v2.3.4 - Fixed bug when working with gzipped streams whereby flushing
* the Base64.OutputStream closed the Base64 encoding (by padding with equals
* the Base64Tools.OutputStream closed the Base64 encoding (by padding with equals
* signs) too soon. Also added an option to suppress the automatic decoding
* of gzipped streams. Also added experimental support for specifying a
* class loader when using the
* {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)}
* {@link #decodeToObject(String, int, ClassLoader)}
* method.</li>
* <li>v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java
* footprint with its CharEncoders and so forth. Fixed some javadocs that were
@ -85,10 +85,10 @@ package org.whispersystems.util;
* encoding/decoding from one file to the next. Also added these Base64 dialects:
* <ol>
* <li>The default is RFC3548 format.</li>
* <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
* <li>Calling Base64Tools.setFormat(Base64Tools.BASE64_FORMAT.URLSAFE_FORMAT) generates
* URL and file name friendly format as described in Section 4 of RFC3548.
* http://www.faqs.org/rfcs/rfc3548.html</li>
* <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
* <li>Calling Base64Tools.setFormat(Base64Tools.BASE64_FORMAT.ORDERED_FORMAT) generates
* URL and file name friendly format that preserves lexical ordering as described
* in http://www.faqs.org/qa/rfcc-1940.html</li>
* </ol>
@ -136,38 +136,38 @@ package org.whispersystems.util;
* @author rob@iharder.net
* @version 2.3.3
*/
public class Base64
class Base64Tools
{
/* ******** P U B L I C F I E L D S ******** */
/* ******** P U B L I C F I E L D S ******** */
/** No options specified. Value is zero. */
public final static int NO_OPTIONS = 0;
/** Specify encoding in first bit. Value is one. */
public final static int ENCODE = 1;
/** Specify decoding in first bit. Value is zero. */
public final static int DECODE = 0;
/** Specify that data should be gzip-compressed in second bit. Value is two. */
public final static int GZIP = 2;
/** Specify that gzipped data should <em>not</em> be automatically gunzipped. */
public final static int DONT_GUNZIP = 4;
/** Do break lines when encoding. Value is 8. */
public final static int DO_BREAK_LINES = 8;
/**
/**
* Encode using Base64-like encoding that is URL- and Filename-safe as described
* in Section 4 of RFC3548:
* in Section 4 of RFC3548:
* <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
* It is important to note that data encoded this way is <em>not</em> officially valid Base64,
* It is important to note that data encoded this way is <em>not</em> officially valid Base64,
* or at the very least should not be called Base64 without also specifying that is
* was encoded using the URL- and Filename-safe dialect.
*/
@ -179,50 +179,50 @@ public class Base64
* <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
*/
public final static int ORDERED = 32;
/* ******** P R I V A T E F I E L D S ******** */
/* ******** P R I V A T E F I E L D S ******** */
/** Maximum line length (76) of Base64 output. */
private final static int MAX_LINE_LENGTH = 76;
/** The equals sign (=) as a byte. */
private final static byte EQUALS_SIGN = (byte)'=';
/** The new line character (\n) as a byte. */
private final static byte NEW_LINE = (byte)'\n';
/** Preferred encoding. */
private final static String PREFERRED_ENCODING = "US-ASCII";
private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */
/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */
/** The 64 valid Base64 values. */
/* Host platform me be something funny like EBCDIC, so we hardcode these values. */
private final static byte[] _STANDARD_ALPHABET = {
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
(byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
};
/**
/**
* Translates a Base64 value to either its 6-bit reconstruction value
* or a negative number indicating some other meaning.
**/
@ -259,30 +259,30 @@ public class Base64
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */
/**
* Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
* Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
* <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
* Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
*/
private final static byte[] _URL_SAFE_ALPHABET = {
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
(byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_'
};
/**
* Used in decoding URL- and Filename-safe dialects of Base64.
* Used in decoding URL- and Filename-safe dialects of Base64Tools.
*/
private final static byte[] _URL_SAFE_DECODABET = {
-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8
@ -345,9 +345,9 @@ public class Base64
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'
};
/**
* Used in decoding the "ordered" dialect of Base64.
* Used in decoding the "ordered" dialect of Base64Tools.
*/
private final static byte[] _ORDERED_DECODABET = {
-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8
@ -387,7 +387,7 @@ public class Base64
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */
@ -427,9 +427,9 @@ public class Base64
} // end getAlphabet
/** Defeats instantiation. */
private Base64(){}
private Base64Tools(){}
@ -564,7 +564,7 @@ public class Base64
while( raw.hasRemaining() ){
int rem = Math.min(3,raw.remaining());
raw.get(raw3,0,rem);
Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
Base64Tools.encode3to4(enc4, raw3, rem, Base64Tools.NO_OPTIONS );
encoded.put(enc4);
} // end input remaining
}
@ -588,7 +588,7 @@ public class Base64
while( raw.hasRemaining() ){
int rem = Math.min(3,raw.remaining());
raw.get(raw3,0,rem);
Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
Base64Tools.encode3to4(enc4, raw3, rem, Base64Tools.NO_OPTIONS );
for( int i = 0; i < 4; i++ ){
encoded.put( (char)(enc4[i] & 0xFF) );
}
@ -640,9 +640,9 @@ public class Base64
* DO_BREAK_LINES: break lines at 76 characters
* </pre>
* <p>
* Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
* Example: <code>encodeObject( myObj, Base64Tools.GZIP )</code> or
* <p>
* Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
* Example: <code>encodeObject( myObj, Base64Tools.GZIP | Base64Tools.DO_BREAK_LINES )</code>
*
* @param serializableObject The object to encode
* @param options Specified options
@ -669,7 +669,7 @@ public class Base64
try {
// ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
baos = new java.io.ByteArrayOutputStream();
b64os = new Base64.OutputStream( baos, ENCODE | options );
b64os = new Base64Tools.OutputStream( baos, ENCODE | options );
if( (options & GZIP) != 0 ){
// Gzip
gzos = new java.util.zip.GZIPOutputStream(b64os);
@ -760,9 +760,9 @@ public class Base64
* <i>Note: Technically, this makes your encoding non-compliant.</i>
* </pre>
* <p>
* Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
* Example: <code>encodeBytes( myData, Base64Tools.GZIP )</code> or
* <p>
* Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
* Example: <code>encodeBytes( myData, Base64Tools.GZIP | Base64Tools.DO_BREAK_LINES )</code>
*
*
* <p>As of v 2.3, if there is an error with the GZIP stream,
@ -828,9 +828,9 @@ public class Base64
* <i>Note: Technically, this makes your encoding non-compliant.</i>
* </pre>
* <p>
* Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
* Example: <code>encodeBytes( myData, Base64Tools.GZIP )</code> or
* <p>
* Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
* Example: <code>encodeBytes( myData, Base64Tools.GZIP | Base64Tools.DO_BREAK_LINES )</code>
*
*
* <p>As of v 2.3, if there is an error with the GZIP stream,
@ -881,7 +881,7 @@ public class Base64
public static byte[] encodeBytesToBytes( byte[] source ) {
byte[] encoded = null;
try {
encoded = encodeBytesToBytes( source, 0, source.length, Base64.NO_OPTIONS );
encoded = encodeBytesToBytes( source, 0, source.length, Base64Tools.NO_OPTIONS );
} catch( java.io.IOException ex ) {
assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
}
@ -932,12 +932,12 @@ public class Base64
if( (options & GZIP) != 0 ) {
java.io.ByteArrayOutputStream baos = null;
java.util.zip.GZIPOutputStream gzos = null;
Base64.OutputStream b64os = null;
Base64Tools.OutputStream b64os = null;
try {
// GZip -> Base64 -> ByteArray
baos = new java.io.ByteArrayOutputStream();
b64os = new Base64.OutputStream( baos, ENCODE | options );
b64os = new Base64Tools.OutputStream( baos, ENCODE | options );
gzos = new java.util.zip.GZIPOutputStream( b64os );
gzos.write( source, off, len );
@ -1138,7 +1138,7 @@ public class Base64
public static byte[] decode( byte[] source ){
byte[] decoded = null;
try {
decoded = decode( source, 0, source.length, Base64.NO_OPTIONS );
decoded = decode( source, 0, source.length, Base64Tools.NO_OPTIONS );
} catch( java.io.IOException ex ) {
assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
}
@ -1345,7 +1345,7 @@ public class Base64
* @since 1.5
*/
public static Object decodeToObject( String encodedObject )
throws java.io.IOException, java.lang.ClassNotFoundException {
throws java.io.IOException, ClassNotFoundException {
return decodeToObject(encodedObject,NO_OPTIONS,null);
}
@ -1368,7 +1368,7 @@ public class Base64
*/
public static Object decodeToObject(
String encodedObject, int options, final ClassLoader loader )
throws java.io.IOException, java.lang.ClassNotFoundException {
throws java.io.IOException, ClassNotFoundException {
// Decode and gunzip if necessary
byte[] objBytes = decode( encodedObject, options );
@ -1407,7 +1407,7 @@ public class Base64
catch( java.io.IOException e ) {
throw e; // Catch and throw in order to execute finally{}
} // end catch
catch( java.lang.ClassNotFoundException e ) {
catch( ClassNotFoundException e ) {
throw e; // Catch and throw in order to execute finally{}
} // end catch
finally {
@ -1441,10 +1441,10 @@ public class Base64
throw new NullPointerException( "Data to encode was null." );
} // end iff
Base64.OutputStream bos = null;
Base64Tools.OutputStream bos = null;
try {
bos = new Base64.OutputStream(
new java.io.FileOutputStream( filename ), Base64.ENCODE );
bos = new Base64Tools.OutputStream(
new java.io.FileOutputStream( filename ), Base64Tools.ENCODE );
bos.write( dataToEncode );
} // end try
catch( java.io.IOException e ) {
@ -1473,10 +1473,10 @@ public class Base64
public static void decodeToFile( String dataToDecode, String filename )
throws java.io.IOException {
Base64.OutputStream bos = null;
Base64Tools.OutputStream bos = null;
try{
bos = new Base64.OutputStream(
new java.io.FileOutputStream( filename ), Base64.DECODE );
bos = new Base64Tools.OutputStream(
new java.io.FileOutputStream( filename ), Base64Tools.DECODE );
bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
} // end try
catch( java.io.IOException e ) {
@ -1509,7 +1509,7 @@ public class Base64
throws java.io.IOException {
byte[] decodedData = null;
Base64.InputStream bis = null;
Base64Tools.InputStream bis = null;
try
{
// Set up some useful variables
@ -1526,9 +1526,9 @@ public class Base64
buffer = new byte[ (int)file.length() ];
// Open a stream
bis = new Base64.InputStream(
bis = new Base64Tools.InputStream(
new java.io.BufferedInputStream(
new java.io.FileInputStream( file ) ), Base64.DECODE );
new java.io.FileInputStream( file ) ), Base64Tools.DECODE );
// Read until done
while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
@ -1570,7 +1570,7 @@ public class Base64
throws java.io.IOException {
String encodedData = null;
Base64.InputStream bis = null;
Base64Tools.InputStream bis = null;
try
{
// Set up some useful variables
@ -1580,9 +1580,9 @@ public class Base64
int numBytes = 0;
// Open a stream
bis = new Base64.InputStream(
bis = new Base64Tools.InputStream(
new java.io.BufferedInputStream(
new java.io.FileInputStream( file ) ), Base64.ENCODE );
new java.io.FileInputStream( file ) ), Base64Tools.ENCODE );
// Read until done
while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
@ -1590,7 +1590,7 @@ public class Base64
} // end while
// Save in a variable to return
encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
encodedData = new String( buffer, 0, length, Base64Tools.PREFERRED_ENCODING );
} // end try
catch( java.io.IOException e ) {
@ -1614,7 +1614,7 @@ public class Base64
public static void encodeFileToFile( String infile, String outfile )
throws java.io.IOException {
String encoded = Base64.encodeFromFile( infile );
String encoded = Base64Tools.encodeFromFile( infile );
java.io.OutputStream out = null;
try{
out = new java.io.BufferedOutputStream(
@ -1642,7 +1642,7 @@ public class Base64
public static void decodeFileToFile( String infile, String outfile )
throws java.io.IOException {
byte[] decoded = Base64.decodeFromFile( infile );
byte[] decoded = Base64Tools.decodeFromFile( infile );
java.io.OutputStream out = null;
try{
out = new java.io.BufferedOutputStream(
@ -1664,7 +1664,7 @@ public class Base64
/**
* A {@link Base64.InputStream} will read data from another
* A {@link Base64Tools.InputStream} will read data from another
* <tt>java.io.InputStream</tt>, given in the constructor,
* and encode/decode to/from Base64 notation on the fly.
*
@ -1685,7 +1685,7 @@ public class Base64
/**
* Constructs a {@link Base64.InputStream} in DECODE mode.
* Constructs a {@link Base64Tools.InputStream} in DECODE mode.
*
* @param in the <tt>java.io.InputStream</tt> from which to read data.
* @since 1.3
@ -1696,7 +1696,7 @@ public class Base64
/**
* Constructs a {@link Base64.InputStream} in
* Constructs a {@link Base64Tools.InputStream} in
* either ENCODE or DECODE mode.
* <p>
* Valid options:<pre>
@ -1705,7 +1705,7 @@ public class Base64
* (only meaningful when encoding)</i>
* </pre>
* <p>
* Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
* Example: <code>new Base64Tools.InputStream( in, Base64Tools.DECODE )</code>
*
*
* @param in the <tt>java.io.InputStream</tt> from which to read data.
@ -1877,7 +1877,7 @@ public class Base64
/**
* A {@link Base64.OutputStream} will write data to another
* A {@link Base64Tools.OutputStream} will write data to another
* <tt>java.io.OutputStream</tt>, given in the constructor,
* and encode/decode to/from Base64 notation on the fly.
*
@ -1898,7 +1898,7 @@ public class Base64
private byte[] decodabet; // Local copies to avoid extra method calls
/**
* Constructs a {@link Base64.OutputStream} in ENCODE mode.
* Constructs a {@link Base64Tools.OutputStream} in ENCODE mode.
*
* @param out the <tt>java.io.OutputStream</tt> to which data will be written.
* @since 1.3
@ -1909,7 +1909,7 @@ public class Base64
/**
* Constructs a {@link Base64.OutputStream} in
* Constructs a {@link Base64Tools.OutputStream} in
* either ENCODE or DECODE mode.
* <p>
* Valid options:<pre>
@ -1918,7 +1918,7 @@ public class Base64
* (only meaningful when encoding)</i>
* </pre>
* <p>
* Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
* Example: <code>new Base64Tools.OutputStream( out, Base64Tools.ENCODE )</code>
*
* @param out the <tt>java.io.OutputStream</tt> to which data will be written.
* @param options Specified options.
@ -1987,7 +1987,7 @@ public class Base64
buffer[ position++ ] = (byte)theByte;
if( position >= bufferLength ) { // Enough to output.
int len = Base64.decode4to3( buffer, 0, b4, 0, options );
int len = Base64Tools.decode4to3( buffer, 0, b4, 0, options );
out.write( b4, 0, len );
position = 0;
} // end if: enough to output

View file

@ -0,0 +1,36 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.core.util
import org.junit.Assert.assertArrayEquals
import org.junit.Test
import kotlin.random.Random
class Base64Test {
@Test
fun `decode - correctly decode all strings regardless of url safety or padding`() {
val stopwatch = Stopwatch("time", 2)
for (len in 0 until 256) {
for (i in 0..2_000) {
val bytes = Random.nextBytes(len)
val padded = Base64.encodeWithPadding(bytes)
val unpadded = Base64.encodeWithoutPadding(bytes)
val urlSafePadded = Base64.encodeUrlSafeWithPadding(bytes)
val urlSafeUnpadded = Base64.encodeUrlSafeWithoutPadding(bytes)
assertArrayEquals(bytes, Base64.decode(padded))
assertArrayEquals(bytes, Base64.decode(unpadded))
assertArrayEquals(bytes, Base64.decode(urlSafePadded))
assertArrayEquals(bytes, Base64.decode(urlSafeUnpadded))
}
}
println(stopwatch.stopAndGetLogString())
}
}

View file

@ -65,6 +65,8 @@ dependencies {
implementation libs.kotlin.stdlib.jdk8
implementation project(":core-util-jvm")
testImplementation testLibs.junit.junit
testImplementation testLibs.assertj.core
testImplementation testLibs.conscrypt.openjdk.uber

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);

Some files were not shown because too many files have changed in this diff Show more