mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-16 03:21:29 +00:00
Merge dev and cleanup
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package org.session.libsignal.utilities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* <p>Encodes and decodes to and from Base64 notation.</p>
|
||||
* <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
|
||||
@@ -714,7 +716,7 @@ public class Base64
|
||||
* @throws NullPointerException if source array is null
|
||||
* @since 1.4
|
||||
*/
|
||||
public static String encodeBytes( byte[] source ) {
|
||||
public static String encodeBytes(@NonNull byte[] source ) {
|
||||
// Since we're not going to have the GZIP encoding turned on,
|
||||
// we're not going to have an java.io.IOException thrown, so
|
||||
// we should not force the user to have to catch it.
|
||||
|
@@ -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 }
|
||||
|
@@ -1,9 +1,25 @@
|
||||
package org.session.libsignal.utilities
|
||||
|
||||
class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val version: String) {
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.LruCache
|
||||
|
||||
/**
|
||||
* Create a Snode from a "-" delimited String if valid, null otherwise.
|
||||
*/
|
||||
fun Snode(string: String): Snode? {
|
||||
val components = string.split("-")
|
||||
val address = components[0]
|
||||
val port = components.getOrNull(1)?.toIntOrNull() ?: return null
|
||||
val ed25519Key = components.getOrNull(2) ?: return null
|
||||
val x25519Key = components.getOrNull(3) ?: return null
|
||||
val version = components.getOrNull(4)?.let(Snode::Version) ?: Snode.Version.ZERO
|
||||
return Snode(address, port, Snode.KeySet(ed25519Key, x25519Key), version)
|
||||
}
|
||||
|
||||
class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val version: Version) {
|
||||
val ip: String get() = address.removePrefix("https://")
|
||||
|
||||
public enum class Method(val rawValue: String) {
|
||||
enum class Method(val rawValue: String) {
|
||||
GetSwarm("get_snodes_for_pubkey"),
|
||||
Retrieve("retrieve"),
|
||||
SendMessage("store"),
|
||||
@@ -19,17 +35,37 @@ class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val v
|
||||
|
||||
data class KeySet(val ed25519Key: String, val x25519Key: String)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return if (other is Snode) {
|
||||
address == other.address && port == other.port
|
||||
} else {
|
||||
false
|
||||
override fun equals(other: Any?) = other is Snode && address == other.address && port == other.port
|
||||
override fun hashCode(): Int = address.hashCode() xor port.hashCode()
|
||||
override fun toString(): String = "$address:$port"
|
||||
|
||||
companion object {
|
||||
private val CACHE = LruCache<String, Version>(100)
|
||||
|
||||
@SuppressLint("NotConstructor")
|
||||
@Synchronized
|
||||
fun Version(value: String) = CACHE[value] ?: Snode.Version(value).also { CACHE.put(value, it) }
|
||||
|
||||
fun Version(parts: List<Int>) = Version(parts.joinToString("."))
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class Version(val value: ULong) {
|
||||
companion object {
|
||||
val ZERO = Version(0UL)
|
||||
private const val MASK_BITS = 16
|
||||
private const val MASK = 0xFFFFUL
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return address.hashCode() xor port.hashCode()
|
||||
}
|
||||
internal constructor(value: String): this(
|
||||
value.splitToSequence(".")
|
||||
.take(4)
|
||||
.map { it.toULongOrNull() ?: 0UL }
|
||||
.foldIndexed(0UL) { i, acc, it ->
|
||||
it.coerceAtMost(MASK) shl (3 - i) * MASK_BITS or acc
|
||||
}
|
||||
)
|
||||
|
||||
override fun toString(): String { return "$address:$port" }
|
||||
operator fun compareTo(other: Version): Int = value.compareTo(other.value)
|
||||
}
|
||||
}
|
||||
|
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user