Merge pull request #1594 from bemusementpark/shared-random

Share SecureRandom
This commit is contained in:
Andrew 2024-08-05 13:09:29 +09:30 committed by GitHub
commit 415264eb0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 98 additions and 155 deletions

View File

@ -33,18 +33,16 @@ import android.view.View
import com.annimon.stream.Stream import com.annimon.stream.Stream
import com.google.android.mms.pdu_alt.CharacterSets import com.google.android.mms.pdu_alt.CharacterSets
import com.google.android.mms.pdu_alt.EncodedStringValue 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.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
import java.io.UnsupportedEncodingException import java.io.UnsupportedEncodingException
import java.security.SecureRandom
import java.util.Arrays
import java.util.Collections import java.util.Collections
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import network.loki.messenger.R
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.components.ComposeText
object Util { object Util {
private val TAG: String = Log.tag(Util::class.java) private val TAG: String = Log.tag(Util::class.java)
@ -248,32 +246,6 @@ object Util {
return result 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? { fun uri(uri: String?): Uri? {
return if (uri == null) null return if (uri == null) null
else Uri.parse(uri) else Uri.parse(uri)

View File

@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.security.SecureRandom;
/** /**
* A provider that is responsible for creating or retrieving the AttachmentSecret model. * 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) { private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret); AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret);
storeAttachmentSecret(context, attachmentSecret); storeAttachmentSecret(context, attachmentSecret);

View File

@ -1,6 +1,8 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -8,7 +10,6 @@ import androidx.annotation.NonNull;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
public class DatabaseSecretProvider { public class DatabaseSecretProvider {
@ -60,9 +61,8 @@ public class DatabaseSecretProvider {
} }
private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) { private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
DatabaseSecret databaseSecret = new DatabaseSecret(secret); DatabaseSecret databaseSecret = new DatabaseSecret(secret);

View File

@ -1,6 +1,8 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.util.Pair; import android.util.Pair;
@ -11,7 +13,6 @@ import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream; import javax.crypto.CipherOutputStream;
@ -31,7 +32,7 @@ public class ModernEncryptingPartOutputStream {
throws IOException throws IOException
{ {
byte[] random = new byte[32]; byte[] random = new byte[32];
new SecureRandom().nextBytes(random); SECURE_RANDOM.nextBytes(random);
try { try {
Mac mac = Mac.getInstance("HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256");

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
@ -26,7 +28,6 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.BitmapUtil;
import java.io.Closeable; import java.io.Closeable;
import java.security.SecureRandom;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -303,7 +304,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
public void updateProfilePicture(String groupID, byte[] newValue) { public void updateProfilePicture(String groupID, byte[] newValue) {
long avatarId; long avatarId;
if (newValue != null) avatarId = Math.abs(new SecureRandom().nextLong()); if (newValue != null) avatarId = Math.abs(SECURE_RANDOM.nextLong());
else avatarId = 0; else avatarId = 0;
@ -458,12 +459,6 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId}); 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) { public boolean hasGroup(@NonNull String groupId) {
try (Cursor cursor = databaseHelper.getReadableDatabase().rawQuery( try (Cursor cursor = databaseHelper.getReadableDatabase().rawQuery(
"SELECT 1 FROM " + TABLE_NAME + " WHERE " + GROUP_ID + " = ? LIMIT 1", "SELECT 1 FROM " + TABLE_NAME + " WHERE " + GROUP_ID + " = ? LIMIT 1",

View File

@ -46,11 +46,11 @@ import org.session.libsession.utilities.IdentityKeyMismatchList
import org.session.libsession.utilities.NetworkFailure import org.session.libsession.utilities.NetworkFailure
import org.session.libsession.utilities.NetworkFailureList import org.session.libsession.utilities.NetworkFailureList
import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled 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.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.JsonUtil
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.ThreadUtils.queue import org.session.libsignal.utilities.ThreadUtils.queue
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment
import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener
@ -66,7 +66,6 @@ import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.util.asSequence import org.thoughtcrime.securesms.util.asSequence
import java.io.Closeable import java.io.Closeable
import java.io.IOException import java.io.IOException
import java.security.SecureRandom
import java.util.LinkedList import java.util.LinkedList
class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : MessagingDatabase(context, databaseHelper) { 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?, inner class OutgoingMessageReader(private val message: OutgoingMediaMessage?,
private val threadId: Long) { private val threadId: Long) {
private val id = SecureRandom().nextLong() private val id = SECURE_RANDOM.nextLong()
val current: MessageRecord val current: MessageRecord
get() { get() {
val slideDeck = SlideDeck(context, message!!.attachments) val slideDeck = SlideDeck(context, message!!.attachments)

View File

@ -17,6 +17,8 @@
*/ */
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
@ -49,7 +51,6 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@ -784,7 +785,7 @@ public class SmsDatabase extends MessagingDatabase {
public OutgoingMessageReader(OutgoingTextMessage message, long threadId) { public OutgoingMessageReader(OutgoingTextMessage message, long threadId) {
this.message = message; this.message = message;
this.threadId = threadId; this.threadId = threadId;
this.id = new SecureRandom().nextLong(); this.id = SECURE_RANDOM.nextLong();
} }
public MessageRecord getCurrent() { public MessageRecord getCurrent() {

View File

@ -1,9 +1,10 @@
package org.thoughtcrime.securesms.glide; package org.thoughtcrime.securesms.glide;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import okhttp3.Headers; import okhttp3.Headers;
import okhttp3.Interceptor; import okhttp3.Interceptor;
@ -30,15 +31,15 @@ public class PaddedHeadersInterceptor implements Interceptor {
private @NonNull Headers getPaddedHeaders(@NonNull Headers headers) { private @NonNull Headers getPaddedHeaders(@NonNull Headers headers) {
return headers.newBuilder() 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(); .build();
} }
private static @NonNull String getRandomString(@NonNull SecureRandom secureRandom, int minLength, int maxLength) { private static @NonNull String getRandomString(int minLength, int maxLength) {
char[] buffer = new char[secureRandom.nextInt(maxLength - minLength) + minLength]; char[] buffer = new char[SECURE_RANDOM.nextInt(maxLength - minLength) + minLength];
for (int i = 0 ; i < buffer.length; i++) { 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); return new String(buffer);

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.logging; package org.thoughtcrime.securesms.logging;
import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK; import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -17,7 +18,6 @@ import java.io.IOException;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -64,7 +64,7 @@ class LogFile {
} }
void writeEntry(@NonNull String entry) throws IOException { void writeEntry(@NonNull String entry) throws IOException {
new SecureRandom().nextBytes(ivBuffer); SECURE_RANDOM.nextBytes(ivBuffer);
byte[] plaintext = entry.getBytes(); byte[] plaintext = entry.getBytes();
try { try {

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.logging; package org.thoughtcrime.securesms.logging;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -9,7 +11,6 @@ import org.session.libsignal.utilities.Base64;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
class LogSecretProvider { class LogSecretProvider {
@ -40,9 +41,8 @@ class LogSecretProvider {
} }
private static byte[] createAndStoreSecret(@NonNull Context context) { private static byte[] createAndStoreSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret);

View File

@ -21,7 +21,6 @@ import android.content.res.Resources
import android.net.Uri import android.net.Uri
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.squareup.phrase.Phrase import com.squareup.phrase.Phrase
import java.security.SecureRandom
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress 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.StringSubstitutionConstants.EMOJI_KEY
import org.session.libsession.utilities.Util.equals import org.session.libsession.utilities.Util.equals
import org.session.libsession.utilities.Util.hashCode import org.session.libsession.utilities.Util.hashCode
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.conversation.v2.Util import org.thoughtcrime.securesms.conversation.v2.Util
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
@ -160,7 +160,7 @@ abstract class Slide(@JvmField protected val context: Context, protected val att
): Attachment { ): Attachment {
val resolvedType = val resolvedType =
Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime) Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime)
val fastPreflightId = SecureRandom().nextLong().toString() val fastPreflightId = SECURE_RANDOM.nextLong().toString()
return UriAttachment( return UriAttachment(
uri, uri,
if (hasThumbnail) uri else null, if (hasThumbnail) uri else null,

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.net; package org.thoughtcrime.securesms.net;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
@ -15,7 +17,6 @@ import org.session.libsignal.utilities.guava.Optional;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -54,7 +55,7 @@ public class ChunkedDataFetcher {
private RequestController fetchChunksWithUnknownTotalSize(@NonNull String url, @NonNull Callback callback) { private RequestController fetchChunksWithUnknownTotalSize(@NonNull String url, @NonNull Callback callback) {
CompositeRequestController compositeController = new CompositeRequestController(); CompositeRequestController compositeController = new CompositeRequestController();
long chunkSize = new SecureRandom().nextInt(1024) + 1024; long chunkSize = SECURE_RANDOM.nextInt(1024) + 1024;
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.cacheControl(NO_CACHE) .cacheControl(NO_CACHE)

View File

@ -1,9 +1,9 @@
package org.thoughtcrime.securesms.permissions; package org.thoughtcrime.securesms.permissions;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
@ -11,9 +11,7 @@ import android.os.Build;
import android.provider.Settings; import android.provider.Settings;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Display; import android.view.Display;
import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Button;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -28,13 +26,10 @@ import org.session.libsession.utilities.ServiceUtil;
import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.LRUCache;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import network.loki.messenger.R;
public class Permissions { public class Permissions {
private static final Map<Integer, PermissionsRequest> OUTSTANDING = new LRUCache<>(2); private static final Map<Integer, PermissionsRequest> OUTSTANDING = new LRUCache<>(2);
@ -172,7 +167,7 @@ public class Permissions {
} }
private void executePermissionsRequest(PermissionsRequest request) { private void executePermissionsRequest(PermissionsRequest request) {
int requestCode = new SecureRandom().nextInt(65434) + 100; int requestCode = SECURE_RANDOM.nextInt(65434) + 100;
synchronized (OUTSTANDING) { synchronized (OUTSTANDING) {
OUTSTANDING.put(requestCode, request); OUTSTANDING.put(requestCode, request);

View File

@ -62,6 +62,7 @@ import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.truncateIdForDisplay import org.session.libsession.utilities.truncateIdForDisplay
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.avatar.AvatarSelection import org.thoughtcrime.securesms.avatar.AvatarSelection
import org.thoughtcrime.securesms.components.ProfilePictureView 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.push
import org.thoughtcrime.securesms.util.show import org.thoughtcrime.securesms.util.show
import java.io.File import java.io.File
import java.security.SecureRandom
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@ -294,7 +294,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
val userConfig = configFactory.user val userConfig = configFactory.user
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
prefs.setProfileAvatarId(SecureRandom().nextInt() ) prefs.setProfileAvatarId(SECURE_RANDOM.nextInt() )
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey) ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
// Attempt to grab the details we require to update the profile picture // Attempt to grab the details we require to update the profile picture

View File

@ -1,8 +1,10 @@
package org.thoughtcrime.securesms.webrtc package org.thoughtcrime.securesms.webrtc
import android.content.Context import android.content.Context
import org.session.libsignal.crypto.shuffledRandom
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.SettableFuture 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.Camera
import org.thoughtcrime.securesms.webrtc.video.CameraEventListener import org.thoughtcrime.securesms.webrtc.video.CameraEventListener
import org.thoughtcrime.securesms.webrtc.video.CameraState import org.thoughtcrime.securesms.webrtc.video.CameraState
@ -22,9 +24,7 @@ import org.webrtc.SurfaceTextureHelper
import org.webrtc.VideoSink import org.webrtc.VideoSink
import org.webrtc.VideoSource import org.webrtc.VideoSource
import org.webrtc.VideoTrack import org.webrtc.VideoTrack
import java.security.SecureRandom
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import kotlin.random.asKotlinRandom
class PeerConnectionWrapper(private val context: Context, class PeerConnectionWrapper(private val context: Context,
private val factory: PeerConnectionFactory, private val factory: PeerConnectionFactory,
@ -49,8 +49,7 @@ class PeerConnectionWrapper(private val context: Context,
private var isInitiator = false private var isInitiator = false
private fun initPeerConnection() { private fun initPeerConnection() {
val random = SecureRandom().asKotlinRandom() val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffledRandom().take(2).map { sub ->
val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffled(random).take(2).map { sub ->
PeerConnection.IceServer.builder("turn:$sub.getsession.org") PeerConnection.IceServer.builder("turn:$sub.getsession.org")
.setUsername("session202111") .setUsername("session202111")
.setPassword("053c268164bc7bd7") .setPassword("053c268164bc7bd7")

View File

@ -12,11 +12,11 @@ import org.session.libsession.utilities.Util.equals
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.streams.ProfileCipherInputStream import org.session.libsignal.streams.ProfileCipherInputStream
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.security.SecureRandom
import java.util.concurrent.ConcurrentSkipListSet import java.util.concurrent.ConcurrentSkipListSet
class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipientAddress: Address): Job { 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()) Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize())
if (recipient.isLocalNumber) { if (recipient.isLocalNumber) {
setProfileAvatarId(context, SecureRandom().nextInt()) setProfileAvatarId(context, SECURE_RANDOM.nextInt())
setProfilePictureURL(context, null) setProfilePictureURL(context, null)
} }
@ -83,7 +83,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address)) decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address))
if (recipient.isLocalNumber) { if (recipient.isLocalNumber) {
setProfileAvatarId(context, SecureRandom().nextInt()) setProfileAvatarId(context, SECURE_RANDOM.nextInt())
setProfilePictureURL(context, profileAvatar) setProfilePictureURL(context, profileAvatar)
} }

View File

@ -10,7 +10,7 @@ import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.MessageReceiveParameters import org.session.libsession.messaging.jobs.MessageReceiveParameters
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.GroupUtil 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.Log
import org.session.libsignal.utilities.Namespace import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.defaultRequiresAuth import org.session.libsignal.utilities.defaultRequiresAuth
@ -104,7 +104,7 @@ class ClosedGroupPollerV2 {
fun poll(groupPublicKey: String): Promise<Unit, Exception> { fun poll(groupPublicKey: String): Promise<Unit, Exception> {
if (!isPolling(groupPublicKey)) { return Promise.of(Unit) } if (!isPolling(groupPublicKey)) { return Promise.of(Unit) }
val promise = SnodeAPI.getSwarm(groupPublicKey).bind { swarm -> 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() } if (!isPolling(groupPublicKey)) { throw PollingCanceledException() }
val currentForkInfo = SnodeAPI.forkInfo val currentForkInfo = SnodeAPI.forkInfo
when { when {

View File

@ -19,8 +19,6 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.MessageReceiveParameters 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.RawResponse
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeModule 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.Log
import org.session.libsignal.utilities.Namespace import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.Snode 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.Timer
import java.util.TimerTask import java.util.TimerTask
import kotlin.time.Duration.Companion.days 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 swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf()
val unusedSnodes = swarm.subtract(usedSnodes) val unusedSnodes = swarm.subtract(usedSnodes)
if (unusedSnodes.isNotEmpty()) { if (unusedSnodes.isNotEmpty()) {
val index = SecureRandom().nextInt(unusedSnodes.size) val index = SECURE_RANDOM.nextInt(unusedSnodes.size)
val nextSnode = unusedSnodes.elementAt(index) val nextSnode = unusedSnodes.elementAt(index)
usedSnodes.add(nextSnode) usedSnodes.add(nextSnode)
Log.d(TAG, "Polling $nextSnode.") Log.d(TAG, "Polling $nextSnode.")

View File

@ -28,7 +28,7 @@ object MessageWrapper {
val webSocketMessage = createWebSocketMessage(envelope) val webSocketMessage = createWebSocketMessage(envelope)
return webSocketMessage.toByteArray() return webSocketMessage.toByteArray()
} catch (e: Exception) { } 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 { private fun createWebSocketMessage(envelope: Envelope): WebSocketMessage {
try { try {
val requestBuilder = WebSocketRequestMessage.newBuilder() return WebSocketMessage.newBuilder().apply {
requestBuilder.verb = "PUT" request = WebSocketRequestMessage.newBuilder().apply {
requestBuilder.path = "/api/v1/message" verb = "PUT"
requestBuilder.id = SecureRandom.getInstance("SHA1PRNG").nextLong() path = "/api/v1/message"
requestBuilder.body = envelope.toByteString() id = SecureRandom.getInstance("SHA1PRNG").nextLong()
val messageBuilder = WebSocketMessage.newBuilder() body = envelope.toByteString()
messageBuilder.request = requestBuilder.build() }.build()
messageBuilder.type = WebSocketMessage.Type.REQUEST type = WebSocketMessage.Type.REQUEST
return messageBuilder.build() }.build()
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.") Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.")
throw Error.FailedToWrapEnvelopeInWebSocketMessage throw Error.FailedToWrapEnvelopeInWebSocketMessage

View File

@ -10,11 +10,10 @@ import okhttp3.Request
import org.session.libsession.messaging.file_server.FileServerApi import org.session.libsession.messaging.file_server.FileServerApi
import org.session.libsession.utilities.AESGCM import org.session.libsession.utilities.AESGCM
import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsession.utilities.AESGCM.EncryptionResult
import org.session.libsession.utilities.Util
import org.session.libsession.utilities.getBodyForOnionRequest import org.session.libsession.utilities.getBodyForOnionRequest
import org.session.libsession.utilities.getHeadersForOnionRequest import org.session.libsession.utilities.getHeadersForOnionRequest
import org.session.libsignal.crypto.getRandomElement import org.session.libsignal.crypto.secureRandom
import org.session.libsignal.crypto.getRandomElementOrNull import org.session.libsignal.crypto.secureRandomOrNull
import org.session.libsignal.database.LokiAPIDatabaseProtocol import org.session.libsignal.database.LokiAPIDatabaseProtocol
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Broadcaster import org.session.libsignal.utilities.Broadcaster
@ -149,7 +148,7 @@ object OnionRequestAPI {
val reusableGuardSnodeCount = reusableGuardSnodes.count() val reusableGuardSnodeCount = reusableGuardSnodes.count()
if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() } if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() }
fun getGuardSnode(): Promise<Snode, Exception> { fun getGuardSnode(): Promise<Snode, Exception> {
val candidate = unusedSnodes.getRandomElementOrNull() val candidate = unusedSnodes.secureRandomOrNull()
?: return Promise.ofFail(InsufficientSnodesException()) ?: return Promise.ofFail(InsufficientSnodesException())
unusedSnodes = unusedSnodes.minus(candidate) unusedSnodes = unusedSnodes.minus(candidate)
Log.d("Loki", "Testing guard snode: $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 // Don't test path snodes as this would reveal the user's IP to them
guardSnodes.minus(reusableGuardSnodes).map { guardSnode -> guardSnodes.minus(reusableGuardSnodes).map { guardSnode ->
val result = listOf( guardSnode ) + (0 until (pathSize - 1)).mapIndexed() { index, _ -> 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 // remove the snode from the unused list and return it
unusedSnodes = unusedSnodes.minus(pathSnode) unusedSnodes = unusedSnodes.minus(pathSnode)
@ -228,9 +227,9 @@ object OnionRequestAPI {
OnionRequestAPI.guardSnodes = guardSnodes OnionRequestAPI.guardSnodes = guardSnodes
fun getPath(paths: List<Path>): Path { fun getPath(paths: List<Path>): Path {
return if (snodeToExclude != null) { return if (snodeToExclude != null) {
paths.filter { !it.contains(snodeToExclude) }.getRandomElement() paths.filter { !it.contains(snodeToExclude) }.secureRandom()
} else { } else {
paths.getRandomElement() paths.secureRandom()
} }
} }
when { when {
@ -273,7 +272,7 @@ object OnionRequestAPI {
path.removeAt(snodeIndex) path.removeAt(snodeIndex)
val unusedSnodes = SnodeAPI.snodePool.minus(oldPaths.flatten()) val unusedSnodes = SnodeAPI.snodePool.minus(oldPaths.flatten())
if (unusedSnodes.isEmpty()) { throw InsufficientSnodesException() } 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 // Don't test the new snode as this would reveal the user's IP
oldPaths.removeAt(pathIndex) oldPaths.removeAt(pathIndex)
val newPaths = oldPaths + listOf( path ) val newPaths = oldPaths + listOf( path )

View File

@ -18,7 +18,8 @@ import nl.komponents.kovenant.task
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.messaging.utilities.SodiumUtilities.sodium 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.database.LokiAPIDatabaseProtocol
import org.session.libsignal.protos.SignalServiceProtos import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Base64 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.Namespace
import org.session.libsignal.utilities.Snode import org.session.libsignal.utilities.Snode
import org.session.libsignal.utilities.ThreadUtils 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.prettifiedDescription
import org.session.libsignal.utilities.retryIfNeeded import org.session.libsignal.utilities.retryIfNeeded
import java.security.SecureRandom import java.security.SecureRandom
@ -209,7 +211,7 @@ object SnodeAPI {
Log.d("Loki", "Persisting snode pool to database.") Log.d("Loki", "Persisting snode pool to database.")
this.snodePool = snodePool this.snodePool = snodePool
try { try {
deferred.resolve(snodePool.getRandomElement()) deferred.resolve(snodePool.secureRandom())
} catch (exception: Exception) { } catch (exception: Exception) {
Log.d("Loki", "Got an empty snode pool from: $target.") Log.d("Loki", "Got an empty snode pool from: $target.")
deferred.reject(SnodeAPI.Error.Generic) deferred.reject(SnodeAPI.Error.Generic)
@ -224,7 +226,7 @@ object SnodeAPI {
} }
return deferred.promise return deferred.promise
} else { } 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> { internal fun getSingleTargetSnode(publicKey: String): Promise<Snode, Exception> {
// SecureRandom() should be cryptographically secure // SecureRandom should be cryptographically secure
return getSwarm(publicKey).map { it.shuffled(SecureRandom()).random() } return getSwarm(publicKey).map { it.shuffledRandom().random() }
} }
// Public API // Public API

View File

@ -13,6 +13,7 @@ import android.text.TextUtils
import android.text.style.StyleSpan import android.text.style.StyleSpan
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.io.* import java.io.*
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.security.SecureRandom import java.security.SecureRandom
@ -292,15 +293,10 @@ object Util {
@JvmStatic @JvmStatic
fun getSecretBytes(size: Int): ByteArray { fun getSecretBytes(size: Int): ByteArray {
val secret = ByteArray(size) val secret = ByteArray(size)
getSecureRandom().nextBytes(secret) SECURE_RANDOM.nextBytes(secret)
return secret return secret
} }
@JvmStatic
fun getSecureRandom(): SecureRandom {
return SecureRandom()
}
@JvmStatic @JvmStatic
fun getFirstNonEmpty(vararg values: String?): String? { fun getFirstNonEmpty(vararg values: String?): String? {
for (value in values) { for (value in values) {
@ -317,18 +313,14 @@ object Util {
} }
@JvmStatic @JvmStatic
fun <T> getRandomElement(elements: Array<T>): T { fun <T> getRandomElement(elements: Array<T>): T = elements[SECURE_RANDOM.nextInt(elements.size)]
return elements[SecureRandom().nextInt(elements.size)]
}
@JvmStatic @JvmStatic
fun getBoldedString(value: String?): CharSequence { fun getBoldedString(value: String?): CharSequence {
if (value.isNullOrEmpty()) { return "" } if (value.isNullOrEmpty()) { return "" }
val spanned = SpannableString(value) return SpannableString(value).also {
spanned.setSpan(StyleSpan(Typeface.BOLD), 0, it.setSpan(StyleSpan(Typeface.BOLD), 0, it.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
spanned.length, }
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
return spanned
} }
@JvmStatic @JvmStatic

View File

@ -1,19 +1,23 @@
package org.session.libsignal.crypto 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. * 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 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) return elementAtOrNull(index)
} }
/** /**
* Uses `SecureRandom` to pick an element from this collection. * Uses `SecureRandom` to pick an element from this collection.
*
* @throws [NullPointerException] if the [Collection] is empty
*/ */
fun <T> Collection<T>.getRandomElement(): T { fun <T> Collection<T>.secureRandom(): T {
return getRandomElementOrNull()!! return secureRandomOrNull()!!
} }
fun <T> Collection<T>.shuffledRandom(): List<T> = shuffled(SECURE_RANDOM)

View File

@ -1,13 +1,13 @@
package org.session.libsignal.streams; package org.session.libsignal.streams;
import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK; 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.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -80,7 +80,7 @@ public class ProfileCipherOutputStream extends DigestingOutputStream {
private byte[] generateNonce() { private byte[] generateNonce() {
byte[] nonce = new byte[12]; byte[] nonce = new byte[12];
new SecureRandom().nextBytes(nonce); SECURE_RANDOM.nextBytes(nonce);
return nonce; return nonce;
} }

View File

@ -5,8 +5,7 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.Response import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.security.SecureRandom
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
@ -35,7 +34,7 @@ object HTTP {
override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() } override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }
} }
val sslContext = SSLContext.getInstance("SSL") val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, arrayOf( trustManager ), SecureRandom()) sslContext.init(null, arrayOf( trustManager ), SECURE_RANDOM)
OkHttpClient().newBuilder() OkHttpClient().newBuilder()
.sslSocketFactory(sslContext.socketFactory, trustManager) .sslSocketFactory(sslContext.socketFactory, trustManager)
.hostnameVerifier { _, _ -> true } .hostnameVerifier { _, _ -> true }
@ -55,7 +54,7 @@ object HTTP {
override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() } override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }
} }
val sslContext = SSLContext.getInstance("SSL") val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, arrayOf( trustManager ), SecureRandom()) sslContext.init(null, arrayOf( trustManager ), SECURE_RANDOM)
return OkHttpClient().newBuilder() return OkHttpClient().newBuilder()
.sslSocketFactory(sslContext.socketFactory, trustManager) .sslSocketFactory(sslContext.socketFactory, trustManager)
.hostnameVerifier { _, _ -> true } .hostnameVerifier { _, _ -> true }

View File

@ -12,12 +12,10 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Util { public class Util {
public static SecureRandom SECURE_RANDOM = new SecureRandom();
public static byte[] join(byte[]... input) { public static byte[] join(byte[]... input) {
try { try {
@ -67,7 +65,7 @@ public class Util {
} }
public static boolean isEmpty(String value) { 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) { 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 { public static String readFully(InputStream in) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
@ -98,7 +89,7 @@ public class Util {
in.close(); in.close();
return new String(bout.toByteArray()); return bout.toString();
} }
public static void readFully(InputStream in, byte[] buffer) throws IOException { public static void readFully(InputStream in, byte[] buffer) throws IOException {
@ -146,9 +137,4 @@ public class Util {
} }
return (int)value; return (int)value;
} }
public static <T> List<T> immutableList(T... elements) {
return Collections.unmodifiableList(Arrays.asList(elements.clone()));
}
} }