Skip to content

Commit

Permalink
feat: Trigger CheckRevocationList use case (WPB-3243) - cherrypick (#…
Browse files Browse the repository at this point in the history
…2458)

* feat: Trigger CheckRevocationList use case (WPB-3243) (#2415)

Co-authored-by: Mojtaba Chenani <[email protected]>
Co-authored-by: boris <[email protected]>

* chore: pass test

---------

Co-authored-by: Mojtaba Chenani <[email protected]>
Co-authored-by: boris <[email protected]>
  • Loading branch information
3 people authored and Augusto César Dias committed Feb 13, 2024
1 parent 3994221 commit bead478
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,83 @@ open class GroupInfoBundle(
var payload: ByteArray
)

open class CommitBundle(
data class CommitBundle(
val commit: ByteArray,
val welcome: ByteArray?,
val groupInfoBundle: GroupInfoBundle,
val crlNewDistributionPoints: List<String>?
)
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as CommitBundle

if (!commit.contentEquals(other.commit)) return false
if (welcome != null) {
if (other.welcome == null) return false
if (!welcome.contentEquals(other.welcome)) return false
} else if (other.welcome != null) return false
if (groupInfoBundle != other.groupInfoBundle) return false
return crlNewDistributionPoints == other.crlNewDistributionPoints
}

override fun hashCode(): Int {
var result = commit.contentHashCode()
result = 31 * result + (welcome?.contentHashCode() ?: 0)
result = 31 * result + groupInfoBundle.hashCode()
result = 31 * result + (crlNewDistributionPoints?.hashCode() ?: 0)
return result
}
}

open class WelcomeBundle(
data class WelcomeBundle(
val groupId: MLSGroupId,
val crlNewDistributionPoints: List<String>?
)

open class RotateBundle(
data class RotateBundle(
var commits: Map<MLSGroupId, CommitBundle>,
var newKeyPackages: List<ByteArray>,
var keyPackageRefsToRemove: List<ByteArray>,
val crlNewDistributionPoints: List<String>?
)

class DecryptedMessageBundle(
data class DecryptedMessageBundle(
val message: ByteArray?,
val commitDelay: Long?,
val senderClientId: CryptoQualifiedClientId?,
val hasEpochChanged: Boolean,
val identity: WireIdentity?,
val crlNewDistributionPoints: List<String>?
)
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as DecryptedMessageBundle

if (message != null) {
if (other.message == null) return false
if (!message.contentEquals(other.message)) return false
} else if (other.message != null) return false
if (commitDelay != other.commitDelay) return false
if (senderClientId != other.senderClientId) return false
if (hasEpochChanged != other.hasEpochChanged) return false
if (identity != other.identity) return false
return crlNewDistributionPoints == other.crlNewDistributionPoints
}

override fun hashCode(): Int {
var result = message?.contentHashCode() ?: 0
result = 31 * result + (commitDelay?.hashCode() ?: 0)
result = 31 * result + (senderClientId?.hashCode() ?: 0)
result = 31 * result + hasEpochChanged.hashCode()
result = 31 * result + (identity?.hashCode() ?: 0)
result = 31 * result + (crlNewDistributionPoints?.hashCode() ?: 0)
return result
}
}

@JvmInline
value class Ed22519Key(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

@file:Suppress("konsist.repositoriesShouldNotAccessFeaturePackageClasses")

package com.wire.kalium.logic.data.conversation

import com.wire.kalium.cryptography.CommitBundle
Expand All @@ -28,6 +30,7 @@ import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.MLSFailure
import com.wire.kalium.logic.NetworkFailure
import com.wire.kalium.logic.data.client.MLSClientProvider
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.event.Event
import com.wire.kalium.logic.data.event.EventDeliveryInfo
import com.wire.kalium.logic.data.id.ConversationId
Expand All @@ -44,6 +47,7 @@ import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysMapper
import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysRepository
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.di.MapperProvider
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.flatMap
import com.wire.kalium.logic.functional.flatMapLeft
Expand Down Expand Up @@ -167,6 +171,8 @@ private fun CoreFailure.getStrategy(
}
}

// TODO: refactor this repository as it's doing too much.
// A Repository should be a dummy class that get and set some values
@Suppress("TooManyFunctions", "LongParameterList")
internal class MLSConversationDataSource(
private val selfUserId: UserId,
Expand All @@ -181,6 +187,8 @@ internal class MLSConversationDataSource(
private val epochsFlow: MutableSharedFlow<GroupID>,
private val proposalTimersFlow: MutableSharedFlow<ProposalTimer>,
private val keyPackageLimitsProvider: KeyPackageLimitsProvider,
private val checkRevocationList: CheckRevocationListUseCase,
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val idMapper: IdMapper = MapperProvider.idMapper(),
private val conversationMapper: ConversationMapper = MapperProvider.conversationMapper(selfUserId),
private val mlsPublicKeysMapper: MLSPublicKeysMapper = MapperProvider.mlsPublicKeyMapper(),
Expand Down Expand Up @@ -220,7 +228,9 @@ internal class MLSConversationDataSource(
epochsFlow.emit(groupID)
}
messages.map {
// TODO: process crlDps from decryptMessage
it.crlNewDistributionPoints?.let { newDistributionPoints ->
checkRevocationList(newDistributionPoints)
}
it.toModel(groupID)
}
}
Expand Down Expand Up @@ -265,7 +275,9 @@ internal class MLSConversationDataSource(
wrapMLSRequest {
mlsClient.joinByExternalCommit(groupInfo)
}.flatMap { commitBundle ->
// TODO: process crlDps from decryptMessage
commitBundle.crlNewDistributionPoints?.let {
checkRevocationList(it)
}
sendCommitBundleForExternalCommit(groupID, commitBundle)
}.onSuccess {
conversationDAO.updateConversationGroupState(
Expand Down Expand Up @@ -363,7 +375,9 @@ internal class MLSConversationDataSource(
wrapMLSRequest {
mlsClient.commitPendingProposals(idMapper.toCryptoModel(groupID))
}.flatMap { commitBundle ->
// TODO: process crlDps from decryptMessage
commitBundle?.crlNewDistributionPoints?.let {
checkRevocationList(it)
}
commitBundle?.let { sendCommitBundle(groupID, it) } ?: Either.Right(Unit)
}.flatMap {
wrapStorageRequest {
Expand Down Expand Up @@ -410,7 +424,9 @@ internal class MLSConversationDataSource(
mlsClient.addMember(idMapper.toCryptoModel(groupID), clientKeyPackageList)
}
}.flatMap { commitBundle ->
// TODO: process crlDps from commitBundle
commitBundle?.crlNewDistributionPoints?.let {
checkRevocationList(it)
}
commitBundle?.let {
sendCommitBundle(groupID, it)
} ?: Either.Right(Unit)
Expand Down Expand Up @@ -522,6 +538,9 @@ internal class MLSConversationDataSource(
wrapMLSRequest {
mlsClient.e2eiRotateAll(e2eiClient, certificateChain, keyPackageLimitsProvider.refillAmount().toUInt())
}.map { rotateBundle ->
rotateBundle.crlNewDistributionPoints?.let {
checkRevocationList(it)
}
if (!isNewClient) {
kaliumLogger.w("enrollment for existing client: upload new keypackages and drop old ones")
keyPackageRepository.replaceKeyPackages(clientId, rotateBundle.newKeyPackages).flatMapLeft {
Expand Down Expand Up @@ -677,4 +696,14 @@ internal class MLSConversationDataSource(
Either.Right(Unit)
}
}

private suspend fun checkRevocationList(crlNewDistributionPoints: List<String>) {
crlNewDistributionPoints.forEach { url ->
checkRevocationList(url).map { newExpiration ->
newExpiration?.let {
certificateRevocationListRepository.addOrUpdateCRL(url, it)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,9 @@ class UserSessionScope internal constructor(
commitBundleEventReceiver,
epochsFlow,
proposalTimersFlow,
keyPackageLimitsProvider
keyPackageLimitsProvider,
checkRevocationList,
certificateRevocationListRepository
)

private val e2eiRepository: E2EIRepository
Expand Down Expand Up @@ -1324,8 +1326,14 @@ class UserSessionScope internal constructor(
)
private val mlsWelcomeHandler: MLSWelcomeEventHandler
get() = MLSWelcomeEventHandlerImpl(
mlsClientProvider, conversationRepository, oneOnOneResolver, client.refillKeyPackages
mlsClientProvider = mlsClientProvider,
conversationRepository = conversationRepository,
oneOnOneResolver = oneOnOneResolver,
refillKeyPackages = client.refillKeyPackages,
checkRevocationList = checkRevocationList,
certificateRevocationListRepository = certificateRevocationListRepository
)

private val renamedConversationHandler: RenamedConversationEventHandler
get() = RenamedConversationEventHandlerImpl(
userStorage.database.conversationDAO, persistMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ import com.wire.kalium.logic.data.client.MLSClientProvider
import com.wire.kalium.logic.data.conversation.Conversation
import com.wire.kalium.logic.data.conversation.ConversationDetails
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.event.Event
import com.wire.kalium.logic.data.event.EventLoggingStatus
import com.wire.kalium.logic.data.event.logEventProcessing
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.id.GroupID
import com.wire.kalium.logic.feature.conversation.mls.OneOnOneResolver
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.feature.keypackage.RefillKeyPackagesResult
import com.wire.kalium.logic.feature.keypackage.RefillKeyPackagesUseCase
import com.wire.kalium.logic.functional.Either
Expand All @@ -49,7 +51,9 @@ internal class MLSWelcomeEventHandlerImpl(
val mlsClientProvider: MLSClientProvider,
val conversationRepository: ConversationRepository,
val oneOnOneResolver: OneOnOneResolver,
val refillKeyPackages: RefillKeyPackagesUseCase
val refillKeyPackages: RefillKeyPackagesUseCase,
val checkRevocationList: CheckRevocationListUseCase,
private val certificateRevocationListRepository: CertificateRevocationListRepository
) : MLSWelcomeEventHandler {
override suspend fun handle(event: Event.Conversation.MLSWelcome): Either<CoreFailure, Unit> =
mlsClientProvider
Expand All @@ -61,8 +65,10 @@ internal class MLSWelcomeEventHandlerImpl(
}.flatMap { groupID ->
conversationRepository.fetchConversationIfUnknown(event.conversationId).map { groupID }
}.flatMap { welcomeBundle ->
welcomeBundle.crlNewDistributionPoints?.let {
checkRevocationList(it)
}
markConversationAsEstablished(GroupID(welcomeBundle.groupId))
// TODO: process crlDps from welcomeBundle
}.flatMap {
resolveConversationIfOneOnOne(event.conversationId)
}
Expand Down Expand Up @@ -97,6 +103,15 @@ internal class MLSWelcomeEventHandlerImpl(
private suspend fun markConversationAsEstablished(groupID: GroupID): Either<CoreFailure, Unit> =
conversationRepository.updateConversationGroupState(groupID, Conversation.ProtocolInfo.MLSCapable.GroupState.ESTABLISHED)

private suspend fun checkRevocationList(crlNewDistributionPoints: List<String>) {
crlNewDistributionPoints.forEach { url ->
checkRevocationList(url).map { newExpiration ->
newExpiration?.let {
certificateRevocationListRepository.addOrUpdateCRL(url, it)
}
}
}
}
private suspend fun resolveConversationIfOneOnOne(conversationId: ConversationId): Either<CoreFailure, Unit> =
conversationRepository.observeConversationDetailsById(conversationId)
.first()
Expand Down
Loading

0 comments on commit bead478

Please sign in to comment.