Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update cert revocation list class [WPB-14835] #3215

Open
wants to merge 5 commits into
base: release/android-cycle-4.6
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.wire.kalium.logic.StorageFailure
import com.wire.kalium.logic.data.client.MLSClientProvider
import com.wire.kalium.logic.data.conversation.mls.MLSAdditionResult
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.e2ei.RevocationListChecker
import com.wire.kalium.logic.data.event.Event
import com.wire.kalium.logic.data.event.Event.Conversation.MLSWelcome
import com.wire.kalium.logic.data.event.EventDeliveryInfo
Expand All @@ -52,7 +53,6 @@ import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysRepository
import com.wire.kalium.logic.data.mlspublickeys.getRemovalKey
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 @@ -213,7 +213,7 @@ internal class MLSConversationDataSource(
private val epochsFlow: MutableSharedFlow<GroupID>,
private val proposalTimersFlow: MutableSharedFlow<ProposalTimer>,
private val keyPackageLimitsProvider: KeyPackageLimitsProvider,
private val checkRevocationList: CheckRevocationListUseCase,
private val revocationListChecker: RevocationListChecker,
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val idMapper: IdMapper = MapperProvider.idMapper(),
private val conversationMapper: ConversationMapper = MapperProvider.conversationMapper(selfUserId),
Expand Down Expand Up @@ -904,7 +904,7 @@ internal class MLSConversationDataSource(

private suspend fun checkRevocationList(crlNewDistributionPoints: List<String>) {
crlNewDistributionPoints.forEach { url ->
checkRevocationList(url).map { newExpiration ->
revocationListChecker.check(url).map { newExpiration ->
newExpiration?.let {
certificateRevocationListRepository.addOrUpdateCRL(url, it)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.logic.data.e2ei

import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.E2EIFailure
import com.wire.kalium.logic.configuration.UserConfigRepository
import com.wire.kalium.logic.data.client.MLSClientProvider
import com.wire.kalium.logic.data.id.CurrentClientIdProvider
import com.wire.kalium.logic.featureFlags.FeatureSupport
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.flatMap
import com.wire.kalium.logic.functional.getOrElse
import com.wire.kalium.logic.functional.map
import com.wire.kalium.logic.kaliumLogger

/**
* Use case to check if the CRL is expired and if so, register CRL and update conversation statuses if there is a change.
*/
internal interface RevocationListChecker {
suspend fun check(url: String): Either<CoreFailure, ULong?>
}

internal class RevocationListCheckerImpl(
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val currentClientIdProvider: CurrentClientIdProvider,
private val mlsClientProvider: MLSClientProvider,
private val featureSupport: FeatureSupport,
private val userConfigRepository: UserConfigRepository,
) : RevocationListChecker {
private val logger = kaliumLogger.withTextTag("CheckRevocationListUseCase")
override suspend fun check(url: String): Either<CoreFailure, ULong?> {
val isE2EIEnabled = getIsE2EIEnabled()

return if (isE2EIEnabled) {
logger.i("checking crl url: $url")
certificateRevocationListRepository.getClientDomainCRL(url).flatMap {
currentClientIdProvider().flatMap { clientId ->
mlsClientProvider.getCoreCrypto(clientId).map { coreCrypto ->
logger.i("registering crl..")
coreCrypto.registerCrl(url, it).run {
this.expiration
}
}
}
}
} else Either.Left(E2EIFailure.Disabled)
}

private fun getIsE2EIEnabled() = userConfigRepository.getE2EISettings().flatMap { settings ->
userConfigRepository.isMLSEnabled()
.map {
it && settings.isRequired && featureSupport.isMLSSupported
}
}.getOrElse(false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepositoryDataSource
import com.wire.kalium.logic.data.e2ei.E2EIRepository
import com.wire.kalium.logic.data.e2ei.E2EIRepositoryImpl
import com.wire.kalium.logic.data.e2ei.RevocationListChecker
import com.wire.kalium.logic.data.e2ei.RevocationListCheckerImpl
import com.wire.kalium.logic.feature.e2ei.usecase.ObserveE2EIConversationsVerificationStatusesUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.ObserveE2EIConversationsVerificationStatusesUseCaseImpl
import com.wire.kalium.logic.data.event.EventDataSource
Expand Down Expand Up @@ -214,8 +216,6 @@ import com.wire.kalium.logic.feature.debug.DebugScope
import com.wire.kalium.logic.feature.e2ei.ACMECertificatesSyncWorker
import com.wire.kalium.logic.feature.e2ei.ACMECertificatesSyncWorkerImpl
import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCaseImpl
import com.wire.kalium.logic.feature.e2ei.usecase.FetchConversationMLSVerificationStatusUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.FetchConversationMLSVerificationStatusUseCaseImpl
import com.wire.kalium.logic.feature.e2ei.usecase.FetchMLSVerificationStatusUseCase
Expand Down Expand Up @@ -649,12 +649,13 @@ class UserSessionScope internal constructor(
memberJoinHandler, memberLeaveHandler
)

private val checkRevocationList: CheckRevocationListUseCase
get() = CheckRevocationListUseCaseImpl(
private val checkRevocationList: RevocationListChecker
get() = RevocationListCheckerImpl(
certificateRevocationListRepository = certificateRevocationListRepository,
currentClientIdProvider = clientIdProvider,
mlsClientProvider = mlsClientProvider,
isE2EIEnabledUseCase = isE2EIEnabled
featureSupport = featureSupport,
userConfigRepository = userConfigRepository
)

private val mlsConversationRepository: MLSConversationRepository
Expand Down Expand Up @@ -1359,7 +1360,7 @@ class UserSessionScope internal constructor(
conversationRepository = conversationRepository,
oneOnOneResolver = oneOnOneResolver,
refillKeyPackages = client.refillKeyPackages,
checkRevocationList = checkRevocationList,
revocationListChecker = checkRevocationList,
certificateRevocationListRepository = certificateRevocationListRepository
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package com.wire.kalium.logic.feature.e2ei

import com.wire.kalium.logger.KaliumLogger
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.data.e2ei.RevocationListChecker
import com.wire.kalium.logic.functional.map
import kotlinx.datetime.Clock

Expand All @@ -29,7 +29,7 @@ import kotlinx.datetime.Clock
*/
class CheckCrlRevocationListUseCase internal constructor(
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val checkRevocationList: CheckRevocationListUseCase,
private val revocationListChecker: RevocationListChecker,
kaliumLogger: KaliumLogger
) {

Expand All @@ -39,7 +39,7 @@ class CheckCrlRevocationListUseCase internal constructor(
logger.i("Checking certificate revocation list (CRL). Force update: $forceUpdate")
certificateRevocationListRepository.getCRLs()?.cRLWithExpirationList?.forEach { crl ->
if (forceUpdate || (crl.expiration < Clock.System.now().epochSeconds.toULong())) {
checkRevocationList(crl.url).map { newExpirationTime ->
revocationListChecker.check(crl.url).map { newExpirationTime ->
newExpirationTime?.let {
certificateRevocationListRepository.addOrUpdateCRL(crl.url, it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,40 @@ package com.wire.kalium.logic.feature.e2ei

import com.wire.kalium.logger.KaliumLogger
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.e2ei.RevocationListChecker
import com.wire.kalium.logic.data.sync.IncrementalSyncRepository
import com.wire.kalium.logic.data.sync.IncrementalSyncStatus
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.functional.map
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.datetime.Clock

/**
* This worker will wait until the sync is done and then check the CRLs if needed.
* This use case will wait until the sync is done and then check the CRLs if needed.
*
*/
interface CertificateRevocationListCheckWorker {
suspend fun execute()
}

/**
* Base implementation of [CertificateRevocationListCheckWorker].
* Base implementation of [SyncCertificateRevocationListUseCase].
* @param certificateRevocationListRepository The CRL repository.
* @param incrementalSyncRepository The incremental sync repository.
* @param checkRevocationList The check revocation list use case.
* @param revocationListChecker The check revocation list use case.
*
*/
internal class CertificateRevocationListCheckWorkerImpl(
class SyncCertificateRevocationListUseCase internal constructor(
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val incrementalSyncRepository: IncrementalSyncRepository,
private val checkRevocationList: CheckRevocationListUseCase,
private val revocationListChecker: RevocationListChecker,
kaliumLogger: KaliumLogger
) : CertificateRevocationListCheckWorker {
) {

private val logger = kaliumLogger.withTextTag("CertificateRevocationListCheckWorker")

override suspend fun execute() {
suspend operator fun invoke() {
logger.d("Starting to monitor")
incrementalSyncRepository.incrementalSyncState
.filter { it is IncrementalSyncStatus.Live }
.collect {
.first { it is IncrementalSyncStatus.Live }
.let {
logger.i("Checking certificate revocation list (CRL)..")
certificateRevocationListRepository.getCRLs()?.cRLWithExpirationList?.forEach { crl ->
if (crl.expiration < Clock.System.now().epochSeconds.toULong()) {
checkRevocationList(crl.url).map { newExpirationTime ->
revocationListChecker.check(crl.url).map { newExpirationTime ->
newExpirationTime?.let {
certificateRevocationListRepository.addOrUpdateCRL(crl.url, it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationsUseCa
import com.wire.kalium.logic.data.conversation.MLSConversationRepository
import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository
import com.wire.kalium.logic.data.e2ei.E2EIRepository
import com.wire.kalium.logic.data.e2ei.RevocationListChecker
import com.wire.kalium.logic.data.id.CurrentClientIdProvider
import com.wire.kalium.logic.data.properties.UserPropertyRepository
import com.wire.kalium.logic.data.session.SessionRepository
Expand All @@ -49,9 +50,7 @@ import com.wire.kalium.logic.feature.auth.ValidateUserHandleUseCaseImpl
import com.wire.kalium.logic.feature.client.FinalizeMLSClientAfterE2EIEnrollment
import com.wire.kalium.logic.feature.client.FinalizeMLSClientAfterE2EIEnrollmentImpl
import com.wire.kalium.logic.feature.conversation.GetAllContactsNotInConversationUseCase
import com.wire.kalium.logic.feature.e2ei.CertificateRevocationListCheckWorker
import com.wire.kalium.logic.feature.e2ei.CertificateRevocationListCheckWorkerImpl
import com.wire.kalium.logic.feature.e2ei.usecase.CheckRevocationListUseCase
import com.wire.kalium.logic.feature.e2ei.SyncCertificateRevocationListUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.EnrollE2EIUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.EnrollE2EIUseCaseImpl
import com.wire.kalium.logic.feature.e2ei.usecase.GetMLSClientIdentityUseCase
Expand Down Expand Up @@ -110,10 +109,11 @@ class UserScope internal constructor(
private val isE2EIEnabledUseCase: IsE2EIEnabledUseCase,
private val certificateRevocationListRepository: CertificateRevocationListRepository,
private val incrementalSyncRepository: IncrementalSyncRepository,
private val checkRevocationList: CheckRevocationListUseCase,
private val checkRevocationList: RevocationListChecker,
private val syncFeatureConfigs: SyncFeatureConfigsUseCase,
private val userScopedLogger: KaliumLogger
) {

private val validateUserHandleUseCase: ValidateUserHandleUseCase get() = ValidateUserHandleUseCaseImpl()
val getSelfUser: GetSelfUserUseCase get() = GetSelfUserUseCaseImpl(userRepository)
val getSelfUserWithTeam: ObserveSelfUserWithTeamUseCase get() = ObserveSelfUserWithTeamUseCaseImpl(userRepository)
Expand Down Expand Up @@ -209,14 +209,14 @@ class UserScope internal constructor(
kaliumLogger = userScopedLogger,
)

val certificateRevocationListCheckWorker: CertificateRevocationListCheckWorker by lazy {
CertificateRevocationListCheckWorkerImpl(
certificateRevocationListRepository = certificateRevocationListRepository,
incrementalSyncRepository = incrementalSyncRepository,
checkRevocationList = checkRevocationList,
kaliumLogger = userScopedLogger,
)
}
val syncCertificateRevocationListUseCase: SyncCertificateRevocationListUseCase
get() =
SyncCertificateRevocationListUseCase(
certificateRevocationListRepository = certificateRevocationListRepository,
incrementalSyncRepository = incrementalSyncRepository,
revocationListChecker = checkRevocationList,
kaliumLogger = userScopedLogger,
)

val featureFlagsSyncWorker: FeatureFlagsSyncWorker by lazy {
FeatureFlagSyncWorkerImpl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ 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.e2ei.RevocationListChecker
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 @@ -52,7 +52,7 @@ internal class MLSWelcomeEventHandlerImpl(
val conversationRepository: ConversationRepository,
val oneOnOneResolver: OneOnOneResolver,
val refillKeyPackages: RefillKeyPackagesUseCase,
val checkRevocationList: CheckRevocationListUseCase,
private val revocationListChecker: RevocationListChecker,
private val certificateRevocationListRepository: CertificateRevocationListRepository
) : MLSWelcomeEventHandler {
override suspend fun handle(event: Event.Conversation.MLSWelcome): Either<CoreFailure, Unit> =
Expand Down Expand Up @@ -105,7 +105,7 @@ internal class MLSWelcomeEventHandlerImpl(

private suspend fun checkRevocationList(crlNewDistributionPoints: List<String>) {
crlNewDistributionPoints.forEach { url ->
checkRevocationList(url).map { newExpiration ->
revocationListChecker.check(url).map { newExpiration ->
newExpiration?.let {
certificateRevocationListRepository.addOrUpdateCRL(url, it)
}
Expand Down
Loading
Loading