mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 04:25:18 +00:00
Merge pull request #1594 from bemusementpark/shared-random
Share SecureRandom
This commit is contained in:
commit
415264eb0d
@ -33,18 +33,16 @@ import android.view.View
|
||||
import com.annimon.stream.Stream
|
||||
import com.google.android.mms.pdu_alt.CharacterSets
|
||||
import com.google.android.mms.pdu_alt.EncodedStringValue
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.components.ComposeText
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.security.SecureRandom
|
||||
import java.util.Arrays
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.components.ComposeText
|
||||
|
||||
object Util {
|
||||
private val TAG: String = Log.tag(Util::class.java)
|
||||
@ -248,32 +246,6 @@ object Util {
|
||||
return result
|
||||
}
|
||||
|
||||
fun getSecretBytes(size: Int): ByteArray {
|
||||
return getSecretBytes(SecureRandom(), size)
|
||||
}
|
||||
|
||||
fun getSecretBytes(secureRandom: SecureRandom, size: Int): ByteArray {
|
||||
val secret = ByteArray(size)
|
||||
secureRandom.nextBytes(secret)
|
||||
return secret
|
||||
}
|
||||
|
||||
fun <T> getRandomElement(elements: Array<T>): T {
|
||||
return elements[SecureRandom().nextInt(elements.size)]
|
||||
}
|
||||
|
||||
fun <T> getRandomElement(elements: List<T>): T {
|
||||
return elements[SecureRandom().nextInt(elements.size)]
|
||||
}
|
||||
|
||||
fun equals(a: Any?, b: Any?): Boolean {
|
||||
return a === b || (a != null && a == b)
|
||||
}
|
||||
|
||||
fun hashCode(vararg objects: Any?): Int {
|
||||
return objects.contentHashCode()
|
||||
}
|
||||
|
||||
fun uri(uri: String?): Uri? {
|
||||
return if (uri == null) null
|
||||
else Uri.parse(uri)
|
||||
|
@ -1,14 +1,14 @@
|
||||
package org.thoughtcrime.securesms.crypto;
|
||||
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* A provider that is responsible for creating or retrieving the AttachmentSecret model.
|
||||
*
|
||||
@ -81,9 +81,8 @@ public class AttachmentSecretProvider {
|
||||
}
|
||||
|
||||
private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] secret = new byte[32];
|
||||
random.nextBytes(secret);
|
||||
SECURE_RANDOM.nextBytes(secret);
|
||||
|
||||
AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret);
|
||||
storeAttachmentSecret(context, attachmentSecret);
|
||||
|
@ -1,6 +1,8 @@
|
||||
package org.thoughtcrime.securesms.crypto;
|
||||
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -8,7 +10,6 @@ import androidx.annotation.NonNull;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class DatabaseSecretProvider {
|
||||
|
||||
@ -60,9 +61,8 @@ public class DatabaseSecretProvider {
|
||||
}
|
||||
|
||||
private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] secret = new byte[32];
|
||||
random.nextBytes(secret);
|
||||
SECURE_RANDOM.nextBytes(secret);
|
||||
|
||||
DatabaseSecret databaseSecret = new DatabaseSecret(secret);
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package org.thoughtcrime.securesms.crypto;
|
||||
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Pair;
|
||||
|
||||
@ -11,7 +13,6 @@ import java.io.OutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
@ -31,7 +32,7 @@ public class ModernEncryptingPartOutputStream {
|
||||
throws IOException
|
||||
{
|
||||
byte[] random = new byte[32];
|
||||
new SecureRandom().nextBytes(random);
|
||||
SECURE_RANDOM.nextBytes(random);
|
||||
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@ -26,7 +28,6 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -303,7 +304,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
|
||||
public void updateProfilePicture(String groupID, byte[] newValue) {
|
||||
long avatarId;
|
||||
|
||||
if (newValue != null) avatarId = Math.abs(new SecureRandom().nextLong());
|
||||
if (newValue != null) avatarId = Math.abs(SECURE_RANDOM.nextLong());
|
||||
else avatarId = 0;
|
||||
|
||||
|
||||
@ -458,12 +459,6 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
|
||||
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId});
|
||||
}
|
||||
|
||||
public byte[] allocateGroupId() {
|
||||
byte[] groupId = new byte[16];
|
||||
new SecureRandom().nextBytes(groupId);
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public boolean hasGroup(@NonNull String groupId) {
|
||||
try (Cursor cursor = databaseHelper.getReadableDatabase().rawQuery(
|
||||
"SELECT 1 FROM " + TABLE_NAME + " WHERE " + GROUP_ID + " = ? LIMIT 1",
|
||||
|
@ -46,11 +46,11 @@ import org.session.libsession.utilities.IdentityKeyMismatchList
|
||||
import org.session.libsession.utilities.NetworkFailure
|
||||
import org.session.libsession.utilities.NetworkFailureList
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled
|
||||
import org.session.libsession.utilities.Util.toIsoBytes
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.utilities.JsonUtil
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.ThreadUtils.queue
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener
|
||||
@ -66,7 +66,6 @@ import org.thoughtcrime.securesms.mms.SlideDeck
|
||||
import org.thoughtcrime.securesms.util.asSequence
|
||||
import java.io.Closeable
|
||||
import java.io.IOException
|
||||
import java.security.SecureRandom
|
||||
import java.util.LinkedList
|
||||
|
||||
class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : MessagingDatabase(context, databaseHelper) {
|
||||
@ -1200,7 +1199,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
||||
|
||||
inner class OutgoingMessageReader(private val message: OutgoingMediaMessage?,
|
||||
private val threadId: Long) {
|
||||
private val id = SecureRandom().nextLong()
|
||||
private val id = SECURE_RANDOM.nextLong()
|
||||
val current: MessageRecord
|
||||
get() {
|
||||
val slideDeck = SlideDeck(context, message!!.attachments)
|
||||
|
@ -17,6 +17,8 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
@ -49,7 +51,6 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
@ -784,7 +785,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
public OutgoingMessageReader(OutgoingTextMessage message, long threadId) {
|
||||
this.message = message;
|
||||
this.threadId = threadId;
|
||||
this.id = new SecureRandom().nextLong();
|
||||
this.id = SECURE_RANDOM.nextLong();
|
||||
}
|
||||
|
||||
public MessageRecord getCurrent() {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package org.thoughtcrime.securesms.glide;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Interceptor;
|
||||
@ -30,15 +31,15 @@ public class PaddedHeadersInterceptor implements Interceptor {
|
||||
|
||||
private @NonNull Headers getPaddedHeaders(@NonNull Headers headers) {
|
||||
return headers.newBuilder()
|
||||
.add(PADDING_HEADER, getRandomString(new SecureRandom(), MIN_RANDOM_BYTES, MAX_RANDOM_BYTES))
|
||||
.add(PADDING_HEADER, getRandomString(MIN_RANDOM_BYTES, MAX_RANDOM_BYTES))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static @NonNull String getRandomString(@NonNull SecureRandom secureRandom, int minLength, int maxLength) {
|
||||
char[] buffer = new char[secureRandom.nextInt(maxLength - minLength) + minLength];
|
||||
private static @NonNull String getRandomString(int minLength, int maxLength) {
|
||||
char[] buffer = new char[SECURE_RANDOM.nextInt(maxLength - minLength) + minLength];
|
||||
|
||||
for (int i = 0 ; i < buffer.length; i++) {
|
||||
buffer[i] = (char) (secureRandom.nextInt(74) + 48); // Random char from 0-Z
|
||||
buffer[i] = (char) (SECURE_RANDOM.nextInt(74) + 48); // Random char from 0-Z
|
||||
}
|
||||
|
||||
return new String(buffer);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.logging;
|
||||
|
||||
import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK;
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@ -17,7 +18,6 @@ import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -64,7 +64,7 @@ class LogFile {
|
||||
}
|
||||
|
||||
void writeEntry(@NonNull String entry) throws IOException {
|
||||
new SecureRandom().nextBytes(ivBuffer);
|
||||
SECURE_RANDOM.nextBytes(ivBuffer);
|
||||
|
||||
byte[] plaintext = entry.getBytes();
|
||||
try {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.thoughtcrime.securesms.logging;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -9,7 +11,6 @@ import org.session.libsignal.utilities.Base64;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
class LogSecretProvider {
|
||||
|
||||
@ -40,9 +41,8 @@ class LogSecretProvider {
|
||||
}
|
||||
|
||||
private static byte[] createAndStoreSecret(@NonNull Context context) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] secret = new byte[32];
|
||||
random.nextBytes(secret);
|
||||
SECURE_RANDOM.nextBytes(secret);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret);
|
||||
|
@ -21,7 +21,6 @@ import android.content.res.Resources
|
||||
import android.net.Uri
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.squareup.phrase.Phrase
|
||||
import java.security.SecureRandom
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress
|
||||
@ -29,6 +28,7 @@ import org.session.libsession.messaging.sending_receiving.attachments.UriAttachm
|
||||
import org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY
|
||||
import org.session.libsession.utilities.Util.equals
|
||||
import org.session.libsession.utilities.Util.hashCode
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
import org.thoughtcrime.securesms.conversation.v2.Util
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
@ -160,7 +160,7 @@ abstract class Slide(@JvmField protected val context: Context, protected val att
|
||||
): Attachment {
|
||||
val resolvedType =
|
||||
Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime)
|
||||
val fastPreflightId = SecureRandom().nextLong().toString()
|
||||
val fastPreflightId = SECURE_RANDOM.nextLong().toString()
|
||||
return UriAttachment(
|
||||
uri,
|
||||
if (hasThumbnail) uri else null,
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.thoughtcrime.securesms.net;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@ -15,7 +17,6 @@ import org.session.libsignal.utilities.guava.Optional;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -54,7 +55,7 @@ public class ChunkedDataFetcher {
|
||||
private RequestController fetchChunksWithUnknownTotalSize(@NonNull String url, @NonNull Callback callback) {
|
||||
CompositeRequestController compositeController = new CompositeRequestController();
|
||||
|
||||
long chunkSize = new SecureRandom().nextInt(1024) + 1024;
|
||||
long chunkSize = SECURE_RANDOM.nextInt(1024) + 1024;
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.cacheControl(NO_CACHE)
|
||||
|
@ -1,9 +1,9 @@
|
||||
package org.thoughtcrime.securesms.permissions;
|
||||
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
@ -11,9 +11,7 @@ import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -28,13 +26,10 @@ import org.session.libsession.utilities.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class Permissions {
|
||||
|
||||
private static final Map<Integer, PermissionsRequest> OUTSTANDING = new LRUCache<>(2);
|
||||
@ -172,7 +167,7 @@ public class Permissions {
|
||||
}
|
||||
|
||||
private void executePermissionsRequest(PermissionsRequest request) {
|
||||
int requestCode = new SecureRandom().nextInt(65434) + 100;
|
||||
int requestCode = SECURE_RANDOM.nextInt(65434) + 100;
|
||||
|
||||
synchronized (OUTSTANDING) {
|
||||
OUTSTANDING.put(requestCode, request);
|
||||
|
@ -62,6 +62,7 @@ import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsession.utilities.truncateIdForDisplay
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.avatar.AvatarSelection
|
||||
import org.thoughtcrime.securesms.components.ProfilePictureView
|
||||
@ -90,7 +91,6 @@ import org.thoughtcrime.securesms.util.NetworkUtils
|
||||
import org.thoughtcrime.securesms.util.push
|
||||
import org.thoughtcrime.securesms.util.show
|
||||
import java.io.File
|
||||
import java.security.SecureRandom
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@ -294,7 +294,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
|
||||
val userConfig = configFactory.user
|
||||
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
|
||||
prefs.setProfileAvatarId(SecureRandom().nextInt() )
|
||||
prefs.setProfileAvatarId(SECURE_RANDOM.nextInt() )
|
||||
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
|
||||
|
||||
// Attempt to grab the details we require to update the profile picture
|
||||
|
@ -1,8 +1,10 @@
|
||||
package org.thoughtcrime.securesms.webrtc
|
||||
|
||||
import android.content.Context
|
||||
import org.session.libsignal.crypto.shuffledRandom
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.SettableFuture
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import org.thoughtcrime.securesms.webrtc.video.Camera
|
||||
import org.thoughtcrime.securesms.webrtc.video.CameraEventListener
|
||||
import org.thoughtcrime.securesms.webrtc.video.CameraState
|
||||
@ -22,9 +24,7 @@ import org.webrtc.SurfaceTextureHelper
|
||||
import org.webrtc.VideoSink
|
||||
import org.webrtc.VideoSource
|
||||
import org.webrtc.VideoTrack
|
||||
import java.security.SecureRandom
|
||||
import java.util.concurrent.ExecutionException
|
||||
import kotlin.random.asKotlinRandom
|
||||
|
||||
class PeerConnectionWrapper(private val context: Context,
|
||||
private val factory: PeerConnectionFactory,
|
||||
@ -49,8 +49,7 @@ class PeerConnectionWrapper(private val context: Context,
|
||||
private var isInitiator = false
|
||||
|
||||
private fun initPeerConnection() {
|
||||
val random = SecureRandom().asKotlinRandom()
|
||||
val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffled(random).take(2).map { sub ->
|
||||
val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffledRandom().take(2).map { sub ->
|
||||
PeerConnection.IceServer.builder("turn:$sub.getsession.org")
|
||||
.setUsername("session202111")
|
||||
.setPassword("053c268164bc7bd7")
|
||||
|
@ -12,11 +12,11 @@ import org.session.libsession.utilities.Util.equals
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.streams.ProfileCipherInputStream
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.security.SecureRandom
|
||||
import java.util.concurrent.ConcurrentSkipListSet
|
||||
|
||||
class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipientAddress: Address): Job {
|
||||
@ -64,7 +64,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
|
||||
Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize())
|
||||
|
||||
if (recipient.isLocalNumber) {
|
||||
setProfileAvatarId(context, SecureRandom().nextInt())
|
||||
setProfileAvatarId(context, SECURE_RANDOM.nextInt())
|
||||
setProfilePictureURL(context, null)
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
|
||||
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address))
|
||||
|
||||
if (recipient.isLocalNumber) {
|
||||
setProfileAvatarId(context, SecureRandom().nextInt())
|
||||
setProfileAvatarId(context, SECURE_RANDOM.nextInt())
|
||||
setProfilePictureURL(context, profileAvatar)
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
import org.session.libsignal.crypto.getRandomElementOrNull
|
||||
import org.session.libsignal.crypto.secureRandomOrNull
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.defaultRequiresAuth
|
||||
@ -104,7 +104,7 @@ class ClosedGroupPollerV2 {
|
||||
fun poll(groupPublicKey: String): Promise<Unit, Exception> {
|
||||
if (!isPolling(groupPublicKey)) { return Promise.of(Unit) }
|
||||
val promise = SnodeAPI.getSwarm(groupPublicKey).bind { swarm ->
|
||||
val snode = swarm.getRandomElementOrNull() ?: throw InsufficientSnodesException() // Should be cryptographically secure
|
||||
val snode = swarm.secureRandomOrNull() ?: throw InsufficientSnodesException() // Should be cryptographically secure
|
||||
if (!isPolling(groupPublicKey)) { throw PollingCanceledException() }
|
||||
val currentForkInfo = SnodeAPI.forkInfo
|
||||
when {
|
||||
|
@ -19,8 +19,6 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||
import org.session.libsession.messaging.messages.control.SharedConfigurationMessage
|
||||
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
||||
import org.session.libsession.snode.RawResponse
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.snode.SnodeModule
|
||||
@ -29,7 +27,7 @@ import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.Snode
|
||||
import java.security.SecureRandom
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import kotlin.time.Duration.Companion.days
|
||||
@ -106,7 +104,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
|
||||
val swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf()
|
||||
val unusedSnodes = swarm.subtract(usedSnodes)
|
||||
if (unusedSnodes.isNotEmpty()) {
|
||||
val index = SecureRandom().nextInt(unusedSnodes.size)
|
||||
val index = SECURE_RANDOM.nextInt(unusedSnodes.size)
|
||||
val nextSnode = unusedSnodes.elementAt(index)
|
||||
usedSnodes.add(nextSnode)
|
||||
Log.d(TAG, "Polling $nextSnode.")
|
||||
|
@ -28,7 +28,7 @@ object MessageWrapper {
|
||||
val webSocketMessage = createWebSocketMessage(envelope)
|
||||
return webSocketMessage.toByteArray()
|
||||
} catch (e: Exception) {
|
||||
throw if (e is Error) { e } else { Error.FailedToWrapData }
|
||||
throw if (e is Error) e else Error.FailedToWrapData
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,15 +49,15 @@ object MessageWrapper {
|
||||
|
||||
private fun createWebSocketMessage(envelope: Envelope): WebSocketMessage {
|
||||
try {
|
||||
val requestBuilder = WebSocketRequestMessage.newBuilder()
|
||||
requestBuilder.verb = "PUT"
|
||||
requestBuilder.path = "/api/v1/message"
|
||||
requestBuilder.id = SecureRandom.getInstance("SHA1PRNG").nextLong()
|
||||
requestBuilder.body = envelope.toByteString()
|
||||
val messageBuilder = WebSocketMessage.newBuilder()
|
||||
messageBuilder.request = requestBuilder.build()
|
||||
messageBuilder.type = WebSocketMessage.Type.REQUEST
|
||||
return messageBuilder.build()
|
||||
return WebSocketMessage.newBuilder().apply {
|
||||
request = WebSocketRequestMessage.newBuilder().apply {
|
||||
verb = "PUT"
|
||||
path = "/api/v1/message"
|
||||
id = SecureRandom.getInstance("SHA1PRNG").nextLong()
|
||||
body = envelope.toByteString()
|
||||
}.build()
|
||||
type = WebSocketMessage.Type.REQUEST
|
||||
}.build()
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.")
|
||||
throw Error.FailedToWrapEnvelopeInWebSocketMessage
|
||||
|
@ -10,11 +10,10 @@ import okhttp3.Request
|
||||
import org.session.libsession.messaging.file_server.FileServerApi
|
||||
import org.session.libsession.utilities.AESGCM
|
||||
import org.session.libsession.utilities.AESGCM.EncryptionResult
|
||||
import org.session.libsession.utilities.Util
|
||||
import org.session.libsession.utilities.getBodyForOnionRequest
|
||||
import org.session.libsession.utilities.getHeadersForOnionRequest
|
||||
import org.session.libsignal.crypto.getRandomElement
|
||||
import org.session.libsignal.crypto.getRandomElementOrNull
|
||||
import org.session.libsignal.crypto.secureRandom
|
||||
import org.session.libsignal.crypto.secureRandomOrNull
|
||||
import org.session.libsignal.database.LokiAPIDatabaseProtocol
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.Broadcaster
|
||||
@ -149,7 +148,7 @@ object OnionRequestAPI {
|
||||
val reusableGuardSnodeCount = reusableGuardSnodes.count()
|
||||
if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() }
|
||||
fun getGuardSnode(): Promise<Snode, Exception> {
|
||||
val candidate = unusedSnodes.getRandomElementOrNull()
|
||||
val candidate = unusedSnodes.secureRandomOrNull()
|
||||
?: return Promise.ofFail(InsufficientSnodesException())
|
||||
unusedSnodes = unusedSnodes.minus(candidate)
|
||||
Log.d("Loki", "Testing guard snode: $candidate.")
|
||||
@ -191,7 +190,7 @@ object OnionRequestAPI {
|
||||
// Don't test path snodes as this would reveal the user's IP to them
|
||||
guardSnodes.minus(reusableGuardSnodes).map { guardSnode ->
|
||||
val result = listOf( guardSnode ) + (0 until (pathSize - 1)).mapIndexed() { index, _ ->
|
||||
var pathSnode = unusedSnodes.getRandomElement()
|
||||
var pathSnode = unusedSnodes.secureRandom()
|
||||
|
||||
// remove the snode from the unused list and return it
|
||||
unusedSnodes = unusedSnodes.minus(pathSnode)
|
||||
@ -228,9 +227,9 @@ object OnionRequestAPI {
|
||||
OnionRequestAPI.guardSnodes = guardSnodes
|
||||
fun getPath(paths: List<Path>): Path {
|
||||
return if (snodeToExclude != null) {
|
||||
paths.filter { !it.contains(snodeToExclude) }.getRandomElement()
|
||||
paths.filter { !it.contains(snodeToExclude) }.secureRandom()
|
||||
} else {
|
||||
paths.getRandomElement()
|
||||
paths.secureRandom()
|
||||
}
|
||||
}
|
||||
when {
|
||||
@ -273,7 +272,7 @@ object OnionRequestAPI {
|
||||
path.removeAt(snodeIndex)
|
||||
val unusedSnodes = SnodeAPI.snodePool.minus(oldPaths.flatten())
|
||||
if (unusedSnodes.isEmpty()) { throw InsufficientSnodesException() }
|
||||
path.add(unusedSnodes.getRandomElement())
|
||||
path.add(unusedSnodes.secureRandom())
|
||||
// Don't test the new snode as this would reveal the user's IP
|
||||
oldPaths.removeAt(pathIndex)
|
||||
val newPaths = oldPaths + listOf( path )
|
||||
|
@ -18,7 +18,8 @@ import nl.komponents.kovenant.task
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.utilities.MessageWrapper
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities.sodium
|
||||
import org.session.libsignal.crypto.getRandomElement
|
||||
import org.session.libsignal.crypto.secureRandom
|
||||
import org.session.libsignal.crypto.shuffledRandom
|
||||
import org.session.libsignal.database.LokiAPIDatabaseProtocol
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsignal.utilities.Base64
|
||||
@ -30,6 +31,7 @@ import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.Snode
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import org.session.libsignal.utilities.prettifiedDescription
|
||||
import org.session.libsignal.utilities.retryIfNeeded
|
||||
import java.security.SecureRandom
|
||||
@ -209,7 +211,7 @@ object SnodeAPI {
|
||||
Log.d("Loki", "Persisting snode pool to database.")
|
||||
this.snodePool = snodePool
|
||||
try {
|
||||
deferred.resolve(snodePool.getRandomElement())
|
||||
deferred.resolve(snodePool.secureRandom())
|
||||
} catch (exception: Exception) {
|
||||
Log.d("Loki", "Got an empty snode pool from: $target.")
|
||||
deferred.reject(SnodeAPI.Error.Generic)
|
||||
@ -224,7 +226,7 @@ object SnodeAPI {
|
||||
}
|
||||
return deferred.promise
|
||||
} else {
|
||||
return Promise.of(snodePool.getRandomElement())
|
||||
return Promise.of(snodePool.secureRandom())
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,8 +243,8 @@ object SnodeAPI {
|
||||
}
|
||||
|
||||
internal fun getSingleTargetSnode(publicKey: String): Promise<Snode, Exception> {
|
||||
// SecureRandom() should be cryptographically secure
|
||||
return getSwarm(publicKey).map { it.shuffled(SecureRandom()).random() }
|
||||
// SecureRandom should be cryptographically secure
|
||||
return getSwarm(publicKey).map { it.shuffledRandom().random() }
|
||||
}
|
||||
|
||||
// Public API
|
||||
|
@ -13,6 +13,7 @@ import android.text.TextUtils
|
||||
import android.text.style.StyleSpan
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import java.io.*
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.SecureRandom
|
||||
@ -292,15 +293,10 @@ object Util {
|
||||
@JvmStatic
|
||||
fun getSecretBytes(size: Int): ByteArray {
|
||||
val secret = ByteArray(size)
|
||||
getSecureRandom().nextBytes(secret)
|
||||
SECURE_RANDOM.nextBytes(secret)
|
||||
return secret
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSecureRandom(): SecureRandom {
|
||||
return SecureRandom()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getFirstNonEmpty(vararg values: String?): String? {
|
||||
for (value in values) {
|
||||
@ -317,18 +313,14 @@ object Util {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T> getRandomElement(elements: Array<T>): T {
|
||||
return elements[SecureRandom().nextInt(elements.size)]
|
||||
}
|
||||
fun <T> getRandomElement(elements: Array<T>): T = elements[SECURE_RANDOM.nextInt(elements.size)]
|
||||
|
||||
@JvmStatic
|
||||
fun getBoldedString(value: String?): CharSequence {
|
||||
if (value.isNullOrEmpty()) { return "" }
|
||||
val spanned = SpannableString(value)
|
||||
spanned.setSpan(StyleSpan(Typeface.BOLD), 0,
|
||||
spanned.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
return spanned
|
||||
return SpannableString(value).also {
|
||||
it.setSpan(StyleSpan(Typeface.BOLD), 0, it.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
@ -1,19 +1,23 @@
|
||||
package org.session.libsignal.crypto
|
||||
|
||||
import java.security.SecureRandom
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
|
||||
/**
|
||||
* Uses `SecureRandom` to pick an element from this collection.
|
||||
*/
|
||||
fun <T> Collection<T>.getRandomElementOrNull(): T? {
|
||||
fun <T> Collection<T>.secureRandomOrNull(): T? {
|
||||
if (isEmpty()) return null
|
||||
val index = SecureRandom().nextInt(size) // SecureRandom() should be cryptographically secure
|
||||
val index = SECURE_RANDOM.nextInt(size) // SecureRandom should be cryptographically secure
|
||||
return elementAtOrNull(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses `SecureRandom` to pick an element from this collection.
|
||||
*
|
||||
* @throws [NullPointerException] if the [Collection] is empty
|
||||
*/
|
||||
fun <T> Collection<T>.getRandomElement(): T {
|
||||
return getRandomElementOrNull()!!
|
||||
fun <T> Collection<T>.secureRandom(): T {
|
||||
return secureRandomOrNull()!!
|
||||
}
|
||||
|
||||
fun <T> Collection<T>.shuffledRandom(): List<T> = shuffled(SECURE_RANDOM)
|
||||
|
@ -1,13 +1,13 @@
|
||||
package org.session.libsignal.streams;
|
||||
|
||||
import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK;
|
||||
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -80,7 +80,7 @@ public class ProfileCipherOutputStream extends DigestingOutputStream {
|
||||
|
||||
private byte[] generateNonce() {
|
||||
byte[] nonce = new byte[12];
|
||||
new SecureRandom().nextBytes(nonce);
|
||||
SECURE_RANDOM.nextBytes(nonce);
|
||||
return nonce;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,7 @@ import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import java.security.SecureRandom
|
||||
import org.session.libsignal.utilities.Util.SECURE_RANDOM
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.net.ssl.SSLContext
|
||||
@ -35,7 +34,7 @@ object HTTP {
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }
|
||||
}
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, arrayOf( trustManager ), SecureRandom())
|
||||
sslContext.init(null, arrayOf( trustManager ), SECURE_RANDOM)
|
||||
OkHttpClient().newBuilder()
|
||||
.sslSocketFactory(sslContext.socketFactory, trustManager)
|
||||
.hostnameVerifier { _, _ -> true }
|
||||
@ -55,7 +54,7 @@ object HTTP {
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }
|
||||
}
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, arrayOf( trustManager ), SecureRandom())
|
||||
sslContext.init(null, arrayOf( trustManager ), SECURE_RANDOM)
|
||||
return OkHttpClient().newBuilder()
|
||||
.sslSocketFactory(sslContext.socketFactory, trustManager)
|
||||
.hostnameVerifier { _, _ -> true }
|
||||
|
@ -12,12 +12,10 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Util {
|
||||
public static SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
|
||||
public static byte[] join(byte[]... input) {
|
||||
try {
|
||||
@ -67,7 +65,7 @@ public class Util {
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String value) {
|
||||
return value == null || value.trim().length() == 0;
|
||||
return value == null || value.trim().isEmpty();
|
||||
}
|
||||
|
||||
public static byte[] getSecretBytes(int size) {
|
||||
@ -80,13 +78,6 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getRandomLengthBytes(int maxSize) {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
byte[] result = new byte[secureRandom.nextInt(maxSize) + 1];
|
||||
secureRandom.nextBytes(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String readFully(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
@ -98,7 +89,7 @@ public class Util {
|
||||
|
||||
in.close();
|
||||
|
||||
return new String(bout.toByteArray());
|
||||
return bout.toString();
|
||||
}
|
||||
|
||||
public static void readFully(InputStream in, byte[] buffer) throws IOException {
|
||||
@ -146,9 +137,4 @@ public class Util {
|
||||
}
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
public static <T> List<T> immutableList(T... elements) {
|
||||
return Collections.unmodifiableList(Arrays.asList(elements.clone()));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user