Skip to content

Commit

Permalink
Merge branch 'develop' into feat/epic-federation-offline-messages
Browse files Browse the repository at this point in the history
  • Loading branch information
yamilmedina committed Mar 27, 2023
2 parents 2966b94 + bf207fa commit af58833
Show file tree
Hide file tree
Showing 120 changed files with 3,099 additions and 978 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.cryptography

package com.wire.kalium.logic.data.location

import com.wire.kalium.network.api.base.model.LocationResponse

class LocationMapper {
fun fromLocationResponse(locationResponse: LocationResponse): Location =
with(locationResponse) { Location(latitude = latitude, longitude = longitude) }
}
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
actual annotation class IgnoreJvm()
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class ProteusClientCryptoBoxImpl constructor(
return false
}

override suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray = withContext(defaultContext) {
wrapException { box.getSession(sessionId.value).remoteFingerprint }
}

/**
* Create the crypto files if missing and call box.open
* this must be called only one time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import java.io.File
import java.io.FileNotFoundException

@Suppress("TooManyFunctions")
class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, private val databaseKey: ProteusDBSecret) : ProteusClient {
class ProteusClientCoreCryptoImpl internal constructor(
private val rootDir: String,
private val databaseKey: ProteusDBSecret
) : ProteusClient {

private val path: String = "$rootDir/$KEYSTORE_NAME"
private lateinit var coreCrypto: CoreCrypto
Expand Down Expand Up @@ -104,6 +107,10 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
return wrapException { coreCrypto.proteusFingerprint().toByteArray() }
}

override suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray = wrapException {
coreCrypto.proteusFingerprintRemote(sessionId.value).toByteArray()
}

override suspend fun newPreKeys(from: Int, count: Int): ArrayList<PreKeyCrypto> {
return wrapException {
from.until(from + count).map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ actual class ProteusClientImpl actual constructor(
return client.getLocalFingerprint()
}

override suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray {
return client.remoteFingerPrint(sessionId)
}

override suspend fun newPreKeys(from: Int, count: Int): List<PreKeyCrypto> {
return client.newPreKeys(from, count)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import okio.Source

actual fun encryptDataWithAES256(data: PlainData, key: AES256Key): EncryptedData = AESEncrypt().encryptData(data, key)

actual fun encryptFileWithAES256(assetDataSource: Source, key: AES256Key, outputSink: Sink) =
AESEncrypt().encryptFile(assetDataSource, key, outputSink)
actual fun encryptFileWithAES256(source: Source, key: AES256Key, sink: Sink) =
AESEncrypt().encryptFile(source, key, sink)

actual fun decryptDataWithAES256(data: EncryptedData, secretKey: AES256Key): PlainData = AESDecrypt(secretKey).decryptData(data)

actual fun decryptFileWithAES256(encryptedDataSource: Source, decryptedDataSink: Sink, secretKey: AES256Key) =
AESDecrypt(secretKey).decryptFile(encryptedDataSource, decryptedDataSink)
actual fun decryptFileWithAES256(source: Source, sink: Sink, secretKey: AES256Key) =
AESDecrypt(secretKey).decryptFile(source, sink)

actual fun generateRandomAES256Key(): AES256Key = AESEncrypt().generateRandomAES256Key()
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ interface ProteusClient {
fun getLocalFingerprint(): ByteArray

@Throws(ProteusException::class, CancellationException::class)
suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray

suspend fun newPreKeys(from: Int, count: Int): List<PreKeyCrypto>

@Throws(ProteusException::class, CancellationException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fun calcMd5(bytes: ByteArray): String =

/**
* Method used to calculate the digested MD5 hash of a relatively small byte array
*
* @param bytes the data to be hashed
* @return the digested md5 hash of the input [bytes] data
* @see calcFileMd5
Expand All @@ -56,6 +57,7 @@ fun calcSHA256(bytes: ByteArray): ByteArray =

/**
* Method used to calculate the digested SHA256 hash of a relatively small byte array
*
* @param bytes the data to be hashed
* @return the digested SHA256 hash of the input [bytes] data
* @see calcFileSHA256
Expand All @@ -76,6 +78,7 @@ fun calcFileSHA256(dataSource: Source): ByteArray? =

/**
* Method used to encrypt a relatively small array of bytes using the AES256 encryption algorithm
*
* @param data the [PlainData] that needs to be encrypted
* @param key the symmetric secret [AES256Key] that will be used for the encryption
* @return the final [EncryptedData], on which the first 16 bytes belong to the initialisation vector
Expand All @@ -88,31 +91,34 @@ expect fun encryptDataWithAES256(

/**
* Method used to decrypt a relatively small array of bytes using the AES256 decryption algorithm
*
* @param data the [EncryptedData] that needs to be decrypted
* @return the decrypted data as a byte array encapsulated in a [PlainData] object
* @see decryptFileWithAES256
*/
expect fun decryptDataWithAES256(data: EncryptedData, secretKey: AES256Key): PlainData

/**
* Method used to encrypt some data stored on the file system using the AES256 encryption algorithm
* @param assetDataSource the path to the data that needs to be encrypted
* Method used to encrypt binary data using the AES256 encryption algorithm
*
* @param source the [Source] of the plain text data that needs to be encrypted
* @param key the symmetric secret [AES256Key] that will be used for the encryption
* @param outputSink the path where the encrypted data will be saved
* @param sink the [Sink] which the encrypted data will be written to
* @return the size of the encrypted data in bytes if the encryption succeeded and 0 otherwise
* @see encryptDataWithAES256
*/
expect fun encryptFileWithAES256(assetDataSource: Source, key: AES256Key, outputSink: Sink): Long
expect fun encryptFileWithAES256(source: Source, key: AES256Key, sink: Sink): Long

/**
* Method used to decrypt some binary data using the AES256 encryption algorithm
* @param encryptedDataSource the [Source] of the encrypted data that needs to be decrypted
* @param decryptedDataSink the output stream data sink invoked to write the decrypted data
*
* @param source the [Source] of the encrypted data that needs to be decrypted
* @param sink the [Sink] to which the plain text data will be written to
* @param secretKey the key used for the decryption
* @return the size of the decrypted data in bytes if the decryption succeeded -1L otherwise
* @see decryptDataWithAES256
*/
expect fun decryptFileWithAES256(encryptedDataSource: Source, decryptedDataSink: Sink, secretKey: AES256Key): Long
expect fun decryptFileWithAES256(source: Source, sink: Sink, secretKey: AES256Key): Long

/**
* Method to generate a random Secret Key via the AES256 ciphering Algorithm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import okio.buffer
import okio.fakefilesystem.FakeFileSystem
import okio.use
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
Expand Down Expand Up @@ -82,7 +83,7 @@ class CryptoUtilsTest {

// Then
assertNotNull(digest)
assertTrue(digest.contentEquals(expectedValue))
assertContentEquals(expectedValue, digest)
}

@Test
Expand Down Expand Up @@ -120,7 +121,7 @@ class CryptoUtilsTest {
// Then
assertTrue(input.size % 16 == 0)
assertEquals(decryptedDataSize, input.size.toLong())
assertTrue(input.contentEquals(decryptedData))
assertContentEquals(decryptedData, input)
}

@Test
Expand Down Expand Up @@ -157,7 +158,7 @@ class CryptoUtilsTest {
assertTrue(encryptedDataSize % 16 == 0)
assertEquals(decryptedData.size, input.size)
assertEquals(decryptedDataSize, input.size.toLong())
assertTrue(input.contentEquals(decryptedData))
assertContentEquals(decryptedData, input)
}

@Test
Expand Down Expand Up @@ -189,8 +190,8 @@ class CryptoUtilsTest {

// Then
assertTrue(input.size % 16 == 0)
assertEquals(decryptedData.data.size, input.size)
assertTrue(input.contentEquals(decryptedData.data))
assertEquals(input.size, decryptedData.data.size)
assertContentEquals(input, decryptedData.data)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.cryptography

package com.wire.kalium.logic.data.location
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
expect annotation class IgnoreJvm()

data class Location(
// val name: String,
val latitude: String,
val longitude: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,38 @@ class ProteusClientTest : BaseProteusClientTest() {
assertNotNull(bobClient.encrypt("Hello World".encodeToByteArray(), aliceSessionId))
}

// TODO: cryptobox4j does not expose the session
@IgnoreIOS // underlying proteus error is not exposed atm
@IgnoreJvm
@IgnoreJS
@Test
fun givenNoSessionExists_whenGettingRemoteFingerPrint_thenReturnSessionNotFound() = runTest {
val bobClient = createProteusClient(createProteusStoreRef(bob.id))
bobClient.openOrCreate()

assertFailsWith<ProteusException> {
bobClient.remoteFingerPrint(aliceSessionId)
}.also {
assertEquals(ProteusException.Code.SESSION_NOT_FOUND, it.code)
}
}

@IgnoreJvm // cryptobox4j does not expose the session
@Test
fun givenSessionExists_whenGettingRemoteFingerPrint_thenReturnSuccess() = runTest {
val aliceClient = createProteusClient(createProteusStoreRef(alice.id))
aliceClient.openOrCreate()

val bobClient = createProteusClient(createProteusStoreRef(bob.id))
bobClient.openOrCreate()

val aliceKey = aliceClient.newPreKeys(0, 10).first()
bobClient.createSession(aliceKey, aliceSessionId)
bobClient.remoteFingerPrint(aliceSessionId).also {
assertEquals(aliceClient.getLocalFingerprint().decodeToString(), it.decodeToString())
}
}

companion object {
val PROTEUS_DB_SECRET = ProteusDBSecret("secret")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class ProteusClientCoreCryptoImpl constructor(private val rootDir: String, priva
return wrapException { coreCrypto.proteusFingerprint().toByteArray() }
}

override suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray {
return wrapException { coreCrypto.proteusFingerprintRemote(sessionId.value).toByteArray() }
}

override suspend fun newPreKeys(from: Int, count: Int): ArrayList<PreKeyCrypto> {
return wrapException {
from.until(from + count).map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ actual class ProteusClientImpl actual constructor(
return client.getLocalFingerprint()
}

override suspend fun remoteFingerPrint(sessionId: CryptoSessionId): ByteArray {
return client.remoteFingerPrint(sessionId)
}

override suspend fun newPreKeys(from: Int, count: Int): List<PreKeyCrypto> {
return client.newPreKeys(from, count)
}
Expand Down
Loading

0 comments on commit af58833

Please sign in to comment.