Skip to content

Commit

Permalink
Merge branch 'develop' into fix/asset_upload_cancel
Browse files Browse the repository at this point in the history
  • Loading branch information
trOnk12 authored Jan 9, 2023
2 parents d1d43fd + 6b1453b commit 5ec165f
Show file tree
Hide file tree
Showing 96 changed files with 1,714 additions and 469 deletions.
2 changes: 1 addition & 1 deletion calling/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ kotlin {
}
val androidMain by getting {
dependencies {
api(libs.avs)
api(files("libs/avs_9_0_2.aar")) // TODO temporary until avs9.0.2 is available on Maven-central
api(libs.jna.map {
project.dependencies.create(it, closureOf<ExternalModuleDependency> {
artifact {
Expand Down
Binary file added calling/libs/avs_9_0_2.aar
Binary file not shown.
1 change: 0 additions & 1 deletion cli/src/main/kotlin/com/wire/kalium/cli/CLIApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class CLIApplication : CliktCommand(allowMultipleSubcommands = true) {
override fun run() = runBlocking {
currentContext.findOrSetObject {
CoreLogic(
clientLabel = "Kalium CLI",
rootPath = "$HOME_DIRECTORY/.kalium/accounts",
kaliumConfigs = KaliumConfigs(
developmentApiEnabled = developmentApiEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ class ProteusClientCryptoBoxImpl constructor(rootDir: String) : ProteusClient {
}
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
return sessionIds.associateWith { sessionId ->
encrypt(message, sessionId)
}
}

override suspend fun encryptWithPreKey(
message: ByteArray,
preKeyCrypto: PreKeyCrypto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import com.wire.crypto.ConversationConfiguration
import com.wire.crypto.ConversationId
import com.wire.crypto.CoreCrypto
import com.wire.crypto.CoreCryptoCallbacks
import com.wire.crypto.CustomConfiguration
import com.wire.crypto.DecryptedMessage
import com.wire.crypto.Invitee
import com.wire.crypto.MlsPublicGroupStateEncryptionType
import com.wire.crypto.MlsRatchetTreeType
import com.wire.crypto.MlsWirePolicy
import io.ktor.util.decodeBase64Bytes
import io.ktor.util.encodeBase64
import java.io.File
import java.time.Duration
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration
import kotlin.time.toJavaDuration

private class Callbacks : CoreCryptoCallbacks {

Expand Down Expand Up @@ -50,15 +55,15 @@ actual class MLSClientImpl actual constructor(
) : MLSClient {

private val coreCrypto: CoreCrypto
private val keyRotationDuration: Duration = Duration.ofDays(30)
private val keyRotationDuration: Duration = 30.toDuration(DurationUnit.DAYS)
private val defaultGroupConfiguration = CustomConfiguration(keyRotationDuration.toJavaDuration(), MlsWirePolicy.PLAINTEXT)

init {
coreCrypto = CoreCrypto(rootDir, databaseKey.value, clientId.toString(), null)
coreCrypto = CoreCrypto(rootDir, databaseKey.value, toUByteList(clientId.toString()), null)
coreCrypto.setCallbacks(Callbacks())
}

override fun clearLocalFiles(): Boolean {
coreCrypto.close()
return File(rootDir).deleteRecursively()
}

Expand Down Expand Up @@ -96,19 +101,12 @@ actual class MLSClientImpl actual constructor(
}

override fun joinByExternalCommit(publicGroupState: ByteArray): CommitBundle {
return toCommitBundle(coreCrypto.joinByExternalCommit(toUByteList(publicGroupState)))
return toCommitBundle(coreCrypto.joinByExternalCommit(toUByteList(publicGroupState), defaultGroupConfiguration))
}

override fun mergePendingGroupFromExternalCommit(groupId: MLSGroupId) {
val conf = ConversationConfiguration(
emptyList(),
CiphersuiteName.MLS_128_DHKEMX25519_AES128GCM_SHA256_ED25519,
keyRotationDuration,
emptyList<Ed22519Key>().map { toUByteList(it.value) }
)

val groupIdAsBytes = toUByteList(groupId.decodeBase64Bytes())
coreCrypto.mergePendingGroupFromExternalCommit(groupIdAsBytes, conf)
coreCrypto.mergePendingGroupFromExternalCommit(groupIdAsBytes)
}

override fun clearPendingGroupExternalCommit(groupId: MLSGroupId) {
Expand All @@ -120,10 +118,9 @@ actual class MLSClientImpl actual constructor(
externalSenders: List<Ed22519Key>
) {
val conf = ConversationConfiguration(
emptyList(),
CiphersuiteName.MLS_128_DHKEMX25519_AES128GCM_SHA256_ED25519,
keyRotationDuration,
externalSenders.map { toUByteList(it.value) }
externalSenders.map { toUByteList(it.value) },
defaultGroupConfiguration
)

val groupIdAsBytes = toUByteList(groupId.decodeBase64Bytes())
Expand All @@ -135,7 +132,7 @@ actual class MLSClientImpl actual constructor(
}

override fun processWelcomeMessage(message: WelcomeMessage): MLSGroupId {
val conversationId = coreCrypto.processWelcomeMessage(toUByteList(message))
val conversationId = coreCrypto.processWelcomeMessage(toUByteList(message), defaultGroupConfiguration)
return toByteArray(conversationId).encodeBase64()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
private lateinit var coreCrypto: CoreCrypto

override fun clearLocalFiles(): Boolean {
coreCrypto.close()
return File(path).deleteRecursively()
}

Expand All @@ -25,8 +24,7 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
override suspend fun openOrCreate() {
coreCrypto = wrapException {
File(rootDir).mkdirs()
// TODO client ID is not relevant for proteus but must be provided atm
val coreCrypto = CoreCrypto(path, databaseKey.value, CLIENT_ID.toString(), null)
val coreCrypto = CoreCrypto.deferredInit(path, databaseKey.value, null)
migrateFromCryptoBoxIfNecessary(coreCrypto)
coreCrypto.proteusInit()
coreCrypto
Expand All @@ -37,8 +35,7 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
val directory = File(rootDir)
if (directory.exists()) {
coreCrypto = wrapException {
// TODO client ID is not relevant for proteus but must be provided atm
val coreCrypto = CoreCrypto(path, databaseKey.value, CLIENT_ID.toString(), null)
val coreCrypto = CoreCrypto.deferredInit(path, databaseKey.value, null)
migrateFromCryptoBoxIfNecessary(coreCrypto)
coreCrypto.proteusInit()
coreCrypto
Expand Down Expand Up @@ -97,16 +94,9 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
}

override suspend fun doesSessionExist(sessionId: CryptoSessionId): Boolean {
// TODO hack until we have the proteusSessionExists API
try {
coreCrypto.proteusDecrypt(sessionId.value, toUByteList(""))
} catch (e: CryptoException) {
if (e.message == "Couldn't find conversation") {
return false
}
return wrapException {
coreCrypto.proteusSessionExists(sessionId.value)
}

return true
}

override suspend fun createSession(preKeyCrypto: PreKeyCrypto, sessionId: CryptoSessionId) {
Expand Down Expand Up @@ -137,6 +127,16 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
}
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
return wrapException {
coreCrypto.proteusEncryptBatched(sessionIds.map { it.value }, toUByteList((message))).mapNotNull { entry ->
CryptoSessionId.fromEncodedString(entry.key)?.let { sessionId ->
sessionId to toByteArray(entry.value)
}
}.toMap()
}
}

override suspend fun encryptWithPreKey(
message: ByteArray,
preKeyCrypto: PreKeyCrypto,
Expand Down Expand Up @@ -177,7 +177,6 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
fun toPreKey(id: Int, data: ByteArray): PreKeyCrypto =
PreKeyCrypto(id, data.encodeBase64())

val CLIENT_ID = CryptoQualifiedID("2380b74d-f321-4c11-b7dd-552a74502e30", "wire.com")
val CRYPTO_BOX_FILES = listOf("identities", "prekeys", "sessions", "version")
const val KEYSTORE_NAME = "keystore"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ actual class ProteusClientImpl actual constructor(rootDir: String, databaseKey:
return client.encrypt(message, sessionId)
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
return client.encryptBatched(message, sessionIds)
}

override suspend fun encryptWithPreKey(message: ByteArray, preKeyCrypto: PreKeyCrypto, sessionId: CryptoSessionId): ByteArray {
return client.encryptWithPreKey(message, preKeyCrypto, sessionId)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringTemplate")

package com.wire.kalium.cryptography

typealias MLSGroupId = String
Expand All @@ -17,6 +19,16 @@ data class CryptoQualifiedID(
val domain: String
) {
override fun toString() = "$value@$domain"

companion object {
private const val QUALIFIED_ID_COMPONENT_COUNT = 2

fun fromEncodedString(value: String): CryptoQualifiedID? {
val components = value.split("@")
if (components.size != QUALIFIED_ID_COMPONENT_COUNT) return null
return CryptoQualifiedID(components[0], components[1])
}
}
}

data class CryptoQualifiedClientId(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ import kotlin.coroutines.cancellation.CancellationException

data class CryptoSessionId(val userId: CryptoUserID, val cryptoClientId: CryptoClientId) {
val value: String = "${userId}_$cryptoClientId"

companion object {
private const val SESSION_ID_COMPONENT_COUNT = 2

fun fromEncodedString(value: String): CryptoSessionId? {
val components = value.split("_")
if (components.size != SESSION_ID_COMPONENT_COUNT) return null

val userId = CryptoUserID.fromEncodedString(components[0])
val clientId = CryptoClientId(components[1])

return if (userId != null) {
CryptoSessionId(userId, clientId)
} else {
null
}
}
}
}

data class PreKeyCrypto(
Expand Down Expand Up @@ -52,6 +70,9 @@ interface ProteusClient {
@Throws(ProteusException::class, CancellationException::class)
suspend fun encrypt(message: ByteArray, sessionId: CryptoSessionId): ByteArray

@Throws(ProteusException::class, CancellationException::class)
suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray>

@Throws(ProteusException::class, CancellationException::class)
suspend fun encryptWithPreKey(message: ByteArray, preKeyCrypto: PreKeyCrypto, sessionId: CryptoSessionId): ByteArray

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.wire.kalium.cryptography

import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull

class SessionIDTest {

@Test
fun givenSessionID_whenCallingToString_EncodesCorrectly() {
assertEquals(ENCODED_SESSION_ID, SESSION_ID.value)
}

@Test
fun givenIncorrectlyEncodedSessionID_whenCallingFromEncodedString_ReturnsNull() {
assertNull(CryptoSessionId.fromEncodedString(ENCODED_QUALIFIED_USER_ID))
}

companion object {
private const val CLIENT_ID_RAW = "client_id"
private const val USER_ID = "user_id"
private const val DOMAIN = "domain"

const val ENCODED_QUALIFIED_USER_ID = "$USER_ID@$DOMAIN"
const val ENCODED_SESSION_ID = "$USER_ID@${DOMAIN}_$CLIENT_ID_RAW"

private val CLIENT_ID = CryptoClientId(CLIENT_ID_RAW)
private val QUALIFIED_USER_ID = CryptoQualifiedID(USER_ID, DOMAIN)
val SESSION_ID = CryptoSessionId(QUALIFIED_USER_ID, CLIENT_ID)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ actual class ProteusClientImpl actual constructor(private val rootDir: String, d
return toData(encrypted)
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
TODO("Not yet implemented")
}

override suspend fun encryptWithPreKey(
message: ByteArray,
preKey: PreKeyCrypto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ actual class ProteusClientImpl actual constructor(rootDir: String, databaseKey:
return Int8Array(encryptedMessage.await()).unsafeCast<ByteArray>()
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
TODO("Not yet implemented")
}

override fun deleteSession(sessionId: CryptoSessionId) {
box.session_delete(sessionId.value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ class ProteusClientCryptoBoxImpl constructor(rootDir: String) : ProteusClient {
return wrapException { box.encryptFromSession(sessionId.value, message) }
}

override suspend fun encryptBatched(message: ByteArray, sessionIds: List<CryptoSessionId>): Map<CryptoSessionId, ByteArray> {
return sessionIds.associateWith { sessionId ->
encrypt(message, sessionId)
}
}

override suspend fun encryptWithPreKey(
message: ByteArray,
preKeyCrypto: PreKeyCrypto,
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pbandk = "0.14.2"
turbine = "0.12.1"
avs = "8.2.16"
jna = "5.6.0"
core-crypto = "0.6.0-pre.4"
core-crypto = "0.6.0-rc.3"
desugar-jdk = "1.1.5"
kermit = "1.2.2"
detekt = "1.19.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ import kotlinx.coroutines.cancel
*/
actual class CoreLogic(
private val appContext: Context,
clientLabel: String,
rootPath: String,
kaliumConfigs: KaliumConfigs
) : CoreLogicCommon(clientLabel, rootPath, kaliumConfigs = kaliumConfigs) {
) : CoreLogicCommon(rootPath, kaliumConfigs) {

override val globalPreferences: Lazy<GlobalPrefProvider> = lazy {
GlobalPrefProvider(appContext, kaliumConfigs.shouldEncryptData)
Expand Down Expand Up @@ -63,7 +62,7 @@ actual class CoreLogic(
kaliumConfigs,
globalPreferences.value,
globalCallManager,
userStorageProvider
userStorageProvider,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal fun UserSessionScope(
kaliumConfigs: KaliumConfigs,
featureSupport: FeatureSupport,
userStorageProvider: UserStorageProvider,
userSessionScopeProvider: UserSessionScopeProvider
userSessionScopeProvider: UserSessionScopeProvider,
): UserSessionScope {
val platformUserStorageProperties =
PlatformUserStorageProperties(applicationContext, SecurityHelper(globalPreferences.passphraseStorage))
Expand Down
Loading

0 comments on commit 5ec165f

Please sign in to comment.