This repository has been archived by the owner on Jun 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 494
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added requestPadding property to all VerficationService requests * Added fake calls to the WebReqeustBuilder * 🚧 initial draft to enable plausible deniability * Switched from SubmissionConstants to KeyType enum everywhere * basic playbook implementation with fake and real requests * Playbook - ensure request pattern for playbooks is always the same VerificationService - apply padding to ensure equal request size (header & body) SecurityHelper - extract hash256 to HashHelper. This simplifies tests that use only the hash function (and therefore don´t need to initialize SecurityHelper and its dependencies) * Implemented random chance of dummy playbook execution on app open Signed-off-by: Kolya Opahle <[email protected]> * Playbook - ignore exceptions for fake requests SubmissionService - add padding header to fake request for same header size WebRequestBuilder - include fake keys in upload (🏗) * DiagnosisKeyService: removed (low value & difficult to test) SubmissionService & SubmitDiagnosisKeysTransaction - inline playbook & backgroundNoise property to prevent issues during testing DiagnosisKeyConstantsTest, SubmissionServiceTest, SubmitDiagnosisKeysTransactionTest & SubmissionViewModelTest - adjusted to changes * Dummy playbook will now be repeated and delayed randomly Signed-off-by: Kolya Opahle <[email protected]> * Linting Signed-off-by: Kolya Opahle <[email protected]> * Initial Code for background noise worker Signed-off-by: Kolya Opahle <[email protected]> * First implementation of noise background worker Signed-off-by: Kolya Opahle <[email protected]> * Linting Signed-off-by: Kolya Opahle <[email protected]> * PlaybookImpl - ensure that fake requests are executed when real requests fail SubmissionService & VerificationService - adjust header name for padding WebRequestBuilder - add padding to dummy submission * BackgroundNoise is now trigger-only PlaybookImpl - include follow-up executions after every playbook - logging SubmissionViewModel.kt, SubmissionService.kt, SubmitDiagnosisKeysTransaction.kt, MainActivity.kt, BackgroundNoisePeriodicWorker.kt, DiagnosisTestResultRetrievalPeriodicWorker.kt - propagate context for coroutine VerificationService - ensure body size of 1000 * WebRequestBuilder.kt - adjust fake key generation PlaybookImplTest.kt - remove unused server.enqueue SubmissionService.kt 6 SubmitDiagnosisKeysTransaction.kt - remove commented out code * revert temporary changes to SubmissionResultPositiveOtherWarningFragment.kt * Background job scheduling implemented Signed-off-by: Kolya Opahle <[email protected]> * - adjust fake key size - remove temporary comment * Moved build work calls to own file to fix linting Signed-off-by: Kolya Opahle <[email protected]> * - initialize coroutine scope within the playbook, revert passing it from outside - remove experimental test dependency for coroutines * - use single endpoint per server for fake requests - reduce request size from 1000 to 250 for the verification server - include dummy registration token in fake request to fulfill verification on server side - prepare for randomized count of submitted keys - always include headers cwa-authorization & cwa-header-padding for submission server * - simplify empty header using constant Co-authored-by: Kolya Opahle <[email protected]>
- Loading branch information
1 parent
53e457f
commit f98ac2d
Showing
34 changed files
with
1,143 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package de.rki.coronawarnapp.http.playbook | ||
|
||
import de.rki.coronawarnapp.http.WebRequestBuilder | ||
import de.rki.coronawarnapp.service.submission.SubmissionConstants | ||
import de.rki.coronawarnapp.storage.LocalData | ||
import de.rki.coronawarnapp.worker.BackgroundWorkScheduler | ||
import kotlin.random.Random | ||
|
||
class BackgroundNoise { | ||
companion object { | ||
@Volatile | ||
private var instance: BackgroundNoise? = null | ||
|
||
fun getInstance(): BackgroundNoise { | ||
return instance ?: synchronized(this) { | ||
instance ?: BackgroundNoise().also { | ||
instance = it | ||
} | ||
} | ||
} | ||
} | ||
|
||
fun scheduleDummyPattern() { | ||
BackgroundWorkScheduler.scheduleBackgroundNoisePeriodicWork() | ||
} | ||
|
||
suspend fun foregroundScheduleCheck() { | ||
if (LocalData.isAllowedToSubmitDiagnosisKeys() == true) { | ||
val chance = Random.nextFloat() * 100 | ||
if (chance < SubmissionConstants.probabilityToExecutePlaybookWhenOpenApp) { | ||
PlaybookImpl(WebRequestBuilder.getInstance()) | ||
.dummy() | ||
} | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package de.rki.coronawarnapp.http.playbook | ||
|
||
import KeyExportFormat | ||
import de.rki.coronawarnapp.service.submission.KeyType | ||
import de.rki.coronawarnapp.util.formatter.TestResult | ||
|
||
interface Playbook { | ||
|
||
suspend fun initialRegistration( | ||
key: String, | ||
keyType: KeyType | ||
): String /* registration token */ | ||
|
||
suspend fun testResult( | ||
registrationToken: String | ||
): TestResult | ||
|
||
suspend fun submission( | ||
registrationToken: String, | ||
keys: List<KeyExportFormat.TemporaryExposureKey> | ||
) | ||
|
||
suspend fun dummy() | ||
} |
144 changes: 144 additions & 0 deletions
144
Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package de.rki.coronawarnapp.http.playbook | ||
|
||
import KeyExportFormat | ||
import de.rki.coronawarnapp.http.WebRequestBuilder | ||
import de.rki.coronawarnapp.service.submission.KeyType | ||
import de.rki.coronawarnapp.service.submission.SubmissionConstants | ||
import de.rki.coronawarnapp.util.formatter.TestResult | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.launch | ||
import timber.log.Timber | ||
import java.util.UUID | ||
import java.util.concurrent.TimeUnit | ||
import kotlin.random.Random | ||
|
||
class PlaybookImpl( | ||
private val webRequestBuilder: WebRequestBuilder | ||
) : Playbook { | ||
|
||
private val uid = UUID.randomUUID().toString() | ||
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO) | ||
|
||
override suspend fun initialRegistration(key: String, keyType: KeyType): String { | ||
Timber.i("[$uid] New Initial Registration Playbook") | ||
|
||
// real registration | ||
val (registrationToken, exception) = | ||
executeCapturingExceptions { webRequestBuilder.asyncGetRegistrationToken(key, keyType) } | ||
|
||
// fake verification | ||
ignoreExceptions { webRequestBuilder.asyncFakeVerification() } | ||
|
||
// fake submission | ||
ignoreExceptions { webRequestBuilder.asyncFakeSubmission() } | ||
|
||
coroutineScope.launch { followUpPlaybooks() } | ||
|
||
return registrationToken ?: propagateException(exception) | ||
} | ||
|
||
override suspend fun testResult(registrationToken: String): TestResult { | ||
Timber.i("[$uid] New Test Result Playbook") | ||
|
||
// real test result | ||
val (testResult, exception) = | ||
executeCapturingExceptions { webRequestBuilder.asyncGetTestResult(registrationToken) } | ||
|
||
// fake verification | ||
ignoreExceptions { webRequestBuilder.asyncFakeVerification() } | ||
|
||
// fake submission | ||
ignoreExceptions { webRequestBuilder.asyncFakeSubmission() } | ||
|
||
coroutineScope.launch { followUpPlaybooks() } | ||
|
||
return testResult?.let { TestResult.fromInt(it) } | ||
?: propagateException(exception) | ||
} | ||
|
||
override suspend fun submission( | ||
registrationToken: String, | ||
keys: List<KeyExportFormat.TemporaryExposureKey> | ||
) { | ||
Timber.i("[$uid] New Submission Playbook") | ||
|
||
// real auth code | ||
val (authCode, exception) = executeCapturingExceptions { | ||
webRequestBuilder.asyncGetTan( | ||
registrationToken | ||
) | ||
} | ||
|
||
// fake verification | ||
ignoreExceptions { webRequestBuilder.asyncFakeVerification() } | ||
|
||
// real submission | ||
if (authCode != null) { | ||
webRequestBuilder.asyncSubmitKeysToServer(authCode, keys) | ||
coroutineScope.launch { followUpPlaybooks() } | ||
} else { | ||
webRequestBuilder.asyncFakeSubmission() | ||
coroutineScope.launch { followUpPlaybooks() } | ||
propagateException(exception) | ||
} | ||
} | ||
|
||
private suspend fun dummy(launchFollowUp: Boolean) { | ||
// fake verification | ||
ignoreExceptions { webRequestBuilder.asyncFakeVerification() } | ||
|
||
// fake verification | ||
ignoreExceptions { webRequestBuilder.asyncFakeVerification() } | ||
|
||
// fake submission | ||
ignoreExceptions { webRequestBuilder.asyncFakeSubmission() } | ||
|
||
if (launchFollowUp) | ||
coroutineScope.launch { followUpPlaybooks() } | ||
} | ||
|
||
override suspend fun dummy() = dummy(true) | ||
|
||
private suspend fun followUpPlaybooks() { | ||
val runsToExecute = Random.nextInt( | ||
SubmissionConstants.minNumberOfSequentialPlaybooks, | ||
SubmissionConstants.maxNumberOfSequentialPlaybooks | ||
) | ||
Timber.i("[$uid] Follow Up: launching $runsToExecute follow up playbooks") | ||
|
||
repeat(runsToExecute) { | ||
val executionDelay = Random.nextInt( | ||
SubmissionConstants.minDelayBetweenSequentialPlaybooks, | ||
SubmissionConstants.maxDelayBetweenSequentialPlaybooks | ||
) | ||
Timber.i("[$uid] Follow Up: (${it + 1}/$runsToExecute) waiting $executionDelay[s]...") | ||
delay(TimeUnit.SECONDS.toMillis(executionDelay.toLong())) | ||
|
||
dummy(false) | ||
} | ||
Timber.i("[$uid] Follow Up: finished") | ||
} | ||
|
||
private suspend fun ignoreExceptions(body: suspend () -> Unit) { | ||
try { | ||
body.invoke() | ||
} catch (e: Exception) { | ||
Timber.d(e, "Ignoring dummy request exception") | ||
} | ||
} | ||
|
||
private suspend fun <T> executeCapturingExceptions(body: suspend () -> T): Pair<T?, Exception?> { | ||
return try { | ||
val result = body.invoke() | ||
result to null | ||
} catch (e: Exception) { | ||
null to e | ||
} | ||
} | ||
|
||
private fun propagateException(exception: Exception?): Nothing { | ||
throw exception ?: IllegalStateException() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
f98ac2d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wee! Wenn ich als Interessierter versuche, den Code nachzuvollziehen, dann ist es sehr schwierig zu verstehen, welche Konzepte hinter Code-Artefakten stehen. Bspw: "Playbook". WTF ist das? Es sind überhaupt keine Kommentare im Code vorhanden, die das Konstrukt beschreiben. Das ist einfach schlechtester Stil. (Hier nur zufällig herausgegriffen. Nicht-Kommentierung findet sich erschrecklich häufig).