diff --git a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/MLSClientImpl.kt b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/MLSClientImpl.kt index 0fda4427a25..6e442fb6c09 100644 --- a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/MLSClientImpl.kt +++ b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/MLSClientImpl.kt @@ -326,14 +326,14 @@ class MLSClientImpl( return clientId?.let { WireIdentity( CryptoQualifiedClientId.fromEncodedString(value.clientId)!!, - value.handle, - value.displayName, - value.domain, - value.certificate, + value.x509Identity?.handle, + value.x509Identity?.displayName, + value.x509Identity?.domain, + value.x509Identity?.certificate, toDeviceStatus(value.status), value.thumbprint, - value.serialNumber, - value.notAfter.toLong() + value.x509Identity?.serialNumber, + value.x509Identity?.notAfter?.toLong() ) } } diff --git a/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/IDs.kt b/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/IDs.kt index 06de52e8369..4754bec9e84 100644 --- a/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/IDs.kt +++ b/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/IDs.kt @@ -78,35 +78,54 @@ data class CryptoQualifiedClientId( data class WireIdentity( val clientId: CryptoQualifiedClientId, - val handle: Handle, - val displayName: String, - val domain: String, - val certificate: String, + val certificate: Certificate?, val status: CryptoCertificateStatus, - val thumbprint: String, - val serialNumber: String, - val endTimestampSeconds: Long ) { - constructor( - clientId: CryptoQualifiedClientId, - handle: String, - displayName: String, - domain: String, - certificate: String, - status: CryptoCertificateStatus, - thumbprint: String, - serialNumber: String, - endTimestampSeconds: Long - ) : this( - clientId = clientId, - handle = Handle.fromString(handle, domain), - displayName = displayName, - domain = domain, - certificate = certificate, - status = status, - thumbprint = thumbprint, - serialNumber = serialNumber, - endTimestampSeconds = endTimestampSeconds + companion object { + @Suppress("LongParameterList") + operator fun invoke( + clientId: CryptoQualifiedClientId, + handle: String?, + displayName: String?, + domain: String?, + certificate: String?, + status: CryptoCertificateStatus, + thumbprint: String?, + serialNumber: String?, + endTimestampSeconds: Long? + ): WireIdentity { + @Suppress("ComplexCondition") + val certificateData = if (handle == null || displayName == null || domain == null || certificate == null + || thumbprint == null || serialNumber == null || endTimestampSeconds == null + ) { + null + } else { + Certificate( + Handle.fromString(handle, domain), + displayName, + domain, + certificate, + thumbprint, + serialNumber, + endTimestampSeconds + ) + } + return WireIdentity( + clientId = clientId, + certificate = certificateData, + status = status + ) + } + } + + data class Certificate( + val handle: Handle, + val displayName: String, + val domain: String, + val certificate: String, + val thumbprint: String, + val serialNumber: String, + val endTimestampSeconds: Long ) // WireIdentity handle format is "{scheme}%40{username}@{domain}" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ccb33decf0d..e2e92b76ec9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -38,7 +38,7 @@ pbandk = "0.14.2" turbine = "1.1.0" avs = "9.7.9" jna = "5.14.0" -core-crypto = "1.0.0-rc.54" +core-crypto = "1.0.0-rc.55" core-crypto-multiplatform = "0.6.0-rc.3-multiplatform-pre1" completeKotlin = "1.1.0" desugar-jdk = "2.0.4" diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/DecryptedMessageBundleMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/DecryptedMessageBundleMapper.kt index 9ee890de50d..9d69be60775 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/DecryptedMessageBundleMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/DecryptedMessageBundleMapper.kt @@ -34,14 +34,16 @@ fun com.wire.kalium.cryptography.DecryptedMessageBundle.toModel(groupID: GroupID }, commitDelay, identity?.let { identity -> - E2EIdentity( - identity.clientId, - identity.handle.handle, - identity.displayName, - identity.domain, - identity.certificate, - identity.status, - identity.thumbprint - ) + identity.certificate?.let { certificate -> + E2EIdentity( + identity.clientId, + certificate.handle.handle, + certificate.displayName, + certificate.domain, + certificate.certificate, + identity.status, + certificate.thumbprint + ) + } } ) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/e2ei/MLSConversationsVerificationStatusesHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/e2ei/MLSConversationsVerificationStatusesHandler.kt index e20cc20e81b..7a458d95ef0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/e2ei/MLSConversationsVerificationStatusesHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/e2ei/MLSConversationsVerificationStatusesHandler.kt @@ -123,8 +123,9 @@ internal class MLSConversationsVerificationStatusesHandlerImpl( val persistedMemberInfo = dbData.members[userId.toDao()] val isUserVerified = wireIdentity.firstOrNull { it.status != CryptoCertificateStatus.VALID || - it.displayName != persistedMemberInfo?.name || - it.handle.handle != persistedMemberInfo.handle + it.certificate == null || + it.certificate?.displayName != persistedMemberInfo?.name || + it.certificate?.handle?.handle != persistedMemberInfo?.handle } == null if (!isUserVerified) { newStatus = VerificationStatus.NOT_VERIFIED diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/E2eiCertificate.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/E2eiCertificate.kt index 233d11805bd..cb2c0f4739e 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/E2eiCertificate.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/E2eiCertificate.kt @@ -27,12 +27,14 @@ data class E2eiCertificate( val endAt: Instant ) { companion object { - fun fromWireIdentity(identity: WireIdentity, certificateStatusMapper: CertificateStatusMapper): E2eiCertificate = - E2eiCertificate( - status = certificateStatusMapper.toCertificateStatus(identity.status), - serialNumber = identity.serialNumber, - certificateDetail = identity.certificate, - endAt = Instant.fromEpochSeconds(identity.endTimestampSeconds) - ) + fun fromWireIdentity(identity: WireIdentity, certificateStatusMapper: CertificateStatusMapper): E2eiCertificate? = + identity.certificate?.let { + E2eiCertificate( + status = certificateStatusMapper.toCertificateStatus(identity.status), + serialNumber = it.serialNumber, + certificateDetail = it.certificate, + endAt = Instant.fromEpochSeconds(it.endTimestampSeconds) + ) + } } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetE2EICertificateUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetE2EICertificateUseCase.kt index 2ada0934127..4dad3be6c0c 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetE2EICertificateUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetE2EICertificateUseCase.kt @@ -39,8 +39,9 @@ class GetE2eiCertificateUseCaseImpl internal constructor( { GetE2EICertificateUseCaseResult.Failure }, { it?.let { - val certificate = E2eiCertificate.fromWireIdentity(it, certificateStatusMapper) - GetE2EICertificateUseCaseResult.Success(certificate) + E2eiCertificate.fromWireIdentity(it, certificateStatusMapper)?.let { certificate -> + GetE2EICertificateUseCaseResult.Success(certificate) + } } ?: GetE2EICertificateUseCaseResult.NotActivated } ) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetMembersE2EICertificateStatusesUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetMembersE2EICertificateStatusesUseCase.kt index cd1d2309a9c..81a91b6b12b 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetMembersE2EICertificateStatusesUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetMembersE2EICertificateStatusesUseCase.kt @@ -59,11 +59,11 @@ fun List.getUserCertificateStatus(certificateStatusMapper: Certifi val certificates = this.map { E2eiCertificate.fromWireIdentity(it, certificateStatusMapper) } - return if (certificates.isEmpty()) { + return if (certificates.isEmpty() || certificates.any { it == null }) { null - } else if (certificates.any { it.status == CertificateStatus.REVOKED }) { + } else if (certificates.any { it!!.status == CertificateStatus.REVOKED }) { CertificateStatus.REVOKED - } else if (certificates.any { it.status == CertificateStatus.EXPIRED }) { + } else if (certificates.any { it!!.status == CertificateStatus.EXPIRED }) { CertificateStatus.EXPIRED } else { CertificateStatus.VALID diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetUserE2EIAllCertificatesUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetUserE2EIAllCertificatesUseCase.kt index 879e0a95d6d..3eee87c5d2d 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetUserE2EIAllCertificatesUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/usecase/GetUserE2EIAllCertificatesUseCase.kt @@ -44,8 +44,9 @@ class GetUserE2eiCertificatesUseCaseImpl internal constructor( mlsConversationRepository.getUserIdentity(userId).map { identities -> val result = mutableMapOf() identities.forEach { - val certificate = E2eiCertificate.fromWireIdentity(it, certificateStatusMapper) - result[it.clientId.value] = certificate + E2eiCertificate.fromWireIdentity(it, certificateStatusMapper)?.let { certificate -> + result[it.clientId.value] = certificate + } } result }.getOrElse(mapOf()) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt index 9c2b75a8c34..d8915d27997 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt @@ -92,16 +92,14 @@ import io.ktor.util.decodeBase64Bytes import io.ktor.util.encodeBase64 import io.mockative.Mock import io.mockative.any -import io.mockative.eq import io.mockative.coEvery import io.mockative.coVerify +import io.mockative.eq import io.mockative.every -import io.mockative.matchers.EqualsMatcher import io.mockative.matches import io.mockative.mock import io.mockative.once import io.mockative.twice -import io.mockative.verify import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first @@ -109,7 +107,6 @@ import kotlinx.coroutines.test.runTest import kotlinx.coroutines.yield import kotlinx.datetime.Instant import kotlin.test.Test -import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertIs @@ -1449,7 +1446,11 @@ class MLSConversationRepositoryTest { val domain = "domain.com" val handleWithSchemeAndDomain = "$scheme://%40$handle@$domain" val groupId = Arrangement.GROUP_ID.value - val wireIdentity = WIRE_IDENTITY.copy(handle = WireIdentity.Handle.fromString(handleWithSchemeAndDomain, domain)) + val wireIdentity = WIRE_IDENTITY.copy( + certificate = WIRE_IDENTITY.certificate!!.copy( + handle = WireIdentity.Handle.fromString(handleWithSchemeAndDomain, domain) + ) + ) val (_, mlsConversationRepository) = Arrangement(testKaliumDispatcher) .withGetEstablishedSelfMLSGroupIdReturns(groupId) .withGetMLSClientSuccessful() @@ -1460,9 +1461,9 @@ class MLSConversationRepositoryTest { // then result.shouldSucceed() { it.forEach { - assertEquals(scheme, it.handle.scheme) - assertEquals(handle, it.handle.handle) - assertEquals(domain, it.handle.domain) + assertEquals(scheme, it.certificate?.handle?.scheme) + assertEquals(handle, it.certificate?.handle?.handle) + assertEquals(domain, it.certificate?.handle?.domain) } } } @@ -1475,7 +1476,11 @@ class MLSConversationRepositoryTest { val domain = "domain.com" val handleWithSchemeAndDomain = "$scheme://%40$handle@$domain" val groupId = Arrangement.GROUP_ID.value - val wireIdentity = WIRE_IDENTITY.copy(handle = WireIdentity.Handle.fromString(handleWithSchemeAndDomain, domain)) + val wireIdentity = WIRE_IDENTITY.copy( + certificate = WIRE_IDENTITY.certificate!!.copy( + handle = WireIdentity.Handle.fromString(handleWithSchemeAndDomain, domain) + ) + ) val (_, mlsConversationRepository) = Arrangement(testKaliumDispatcher) .withGetMLSGroupIdByConversationIdReturns(groupId) .withGetMLSClientSuccessful() @@ -1487,9 +1492,9 @@ class MLSConversationRepositoryTest { result.shouldSucceed() { it.values.forEach { it.forEach { - assertEquals(scheme, it.handle.scheme) - assertEquals(handle, it.handle.handle) - assertEquals(domain, it.handle.domain) + assertEquals(scheme, it.certificate?.handle?.scheme) + assertEquals(handle, it.certificate?.handle?.handle) + assertEquals(domain, it.certificate?.handle?.domain) } } }