diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json index d9e5760d18c49446ddd794d9b8116cde3f2286e1..ae4411da473cb49eb102d552dcf25abf7e4053c2 100644 --- a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json +++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "3017a63593d3342376a56b56743815b7", + "identityHash": "06285e5c436b0ac4ef046ec858b505c0", "entities": [ { "tableName": "checkin", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `guid` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `traceLocationBytesBase64` TEXT NOT NULL, `signatureBase64` TEXT NOT NULL, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `guid` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL)", "fields": [ { "fieldPath": "id", @@ -62,18 +62,6 @@ "affinity": "INTEGER", "notNull": false }, - { - "fieldPath": "traceLocationBytesBase64", - "columnName": "traceLocationBytesBase64", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "signatureBase64", - "columnName": "signatureBase64", - "affinity": "TEXT", - "notNull": true - }, { "fieldPath": "checkInStart", "columnName": "checkInStart", @@ -236,7 +224,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3017a63593d3342376a56b56743815b7')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '06285e5c436b0ac4ef046ec858b505c0')" ] } } \ No newline at end of file diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt index 463f705d2303b2dd741325372412eac86ac3e1a7..81af820c4a8b2316030a4ada1fe1212471715edc 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt @@ -1,209 +1,184 @@ package de.rki.coronawarnapp.eventregistration.checkins.qrcode -import de.rki.coronawarnapp.environment.EnvironmentSetup -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.util.base32 -import de.rki.coronawarnapp.util.decodeBase32 -import de.rki.coronawarnapp.util.security.SignatureValidation -import io.kotest.assertions.throwables.shouldNotThrowAny -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import io.mockk.MockKAnnotations -import io.mockk.every -import io.mockk.impl.annotations.MockK -import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString.Companion.toByteString -import org.joda.time.Instant -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import testhelpers.BaseTestInstrumentation - -@RunWith(JUnit4::class) +/*@RunWith(JUnit4::class) class VerifiedTraceLocationTest : BaseTestInstrumentation() { - @MockK lateinit var environmentSetup: EnvironmentSetup - private lateinit var traceLocationQRCodeVerifier: TraceLocationQRCodeVerifier +@MockK lateinit var environmentSetup: EnvironmentSetup - @Before - fun setUp() { - MockKAnnotations.init(this) - every { environmentSetup.appConfigVerificationKey } returns PUB_KEY - traceLocationQRCodeVerifier = TraceLocationQRCodeVerifier(SignatureValidation(environmentSetup)) - } +@Before +fun setUp() { + MockKAnnotations.init(this) + every { environmentSetup.appConfigVerificationKey } returns PUB_KEY +} - @Test - fun verifyEventSuccess() = runBlockingTest { - val instant = Instant.ofEpochMilli(2687960 * 1_000L) - shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe false - traceLocation.isAfterEndTime(instant) shouldBe false - } - } +disabled because of incompatibilities due to latest tech spec changes... needs to be re-written anyway + +@Test +fun verifyEventSuccess() = runBlockingTest { +val instant = Instant.ofEpochMilli(2687960 * 1_000L) +shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe false + traceLocation.isAfterEndTime(instant) shouldBe false } +} +} - /* disabled because of incompatibilities due to tech spec changes... needs to be re-written anyway - - @Test - fun verifyParcelization() = runBlockingTest { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - - val expectedTraceLocation = TraceLocation( - guid = "3055331c-2306-43f3-9742-6d8fab54e848", - version = 1, - type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, - description = "My Birthday Party", - address = "at my place", - startDate = Instant.ofEpochSecond(2687955), - endDate = Instant.ofEpochSecond(2687991), - defaultCheckInLengthInMinutes = 0, - byteRepresentation = verifyResult.traceLocationBytes, - signature = verifyResult.signature.toByteArray().toByteString(), - ) - - verifyResult.traceLocation shouldBe expectedTraceLocation - - val bundle = Bundle().apply { - putParcelable("test", verifyResult.traceLocation) - } - - val parcelRaw = Parcel.obtain().apply { - writeBundle(bundle) - }.marshall() - - val restoredParcel = Parcel.obtain().apply { - unmarshall(parcelRaw, 0, parcelRaw.size) - setDataPosition(0) - } - - val restoredData = restoredParcel.readBundle()!!.run { - classLoader = TraceLocation::class.java.classLoader - getParcelable<TraceLocation>("test") - } - restoredData shouldBe expectedTraceLocation - } - */ - - @Test - fun verifyEventStartTimeWaning() = runBlockingTest { - val instant = Instant.ofEpochMilli(2687940 * 1_000L) - shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe true - traceLocation.isAfterEndTime(instant) shouldBe false - } - } - } +@Test +fun verifyParcelization() = runBlockingTest { +val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + +val expectedTraceLocation = TraceLocation( + guid = "3055331c-2306-43f3-9742-6d8fab54e848", + version = 1, + type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, + description = "My Birthday Party", + address = "at my place", + startDate = Instant.ofEpochSecond(2687955), + endDate = Instant.ofEpochSecond(2687991), + defaultCheckInLengthInMinutes = 0, + byteRepresentation = verifyResult.traceLocationBytes, + signature = verifyResult.signature.toByteArray().toByteString(), +) + +verifyResult.traceLocation shouldBe expectedTraceLocation + +val bundle = Bundle().apply { + putParcelable("test", verifyResult.traceLocation) +} - @Test - fun verifyEventEndTimeWarning() = runBlockingTest { - val instant = Instant.now() - shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe false - traceLocation.isAfterEndTime(instant) shouldBe true - } - } - } +val parcelRaw = Parcel.obtain().apply { + writeBundle(bundle) +}.marshall() - @Test - fun verifyEventWithInvalidKey() = runBlockingTest { - every { environmentSetup.appConfigVerificationKey } returns INVALID_PUB_KEY - shouldThrow<InvalidQRCodeSignatureException> { - traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - } +val restoredParcel = Parcel.obtain().apply { + unmarshall(parcelRaw, 0, parcelRaw.size) + setDataPosition(0) +} + +val restoredData = restoredParcel.readBundle()!!.run { + classLoader = TraceLocation::class.java.classLoader + getParcelable<TraceLocation>("test") +} +restoredData shouldBe expectedTraceLocation +} + +@Test +fun verifyEventStartTimeWaning() = runBlockingTest { +val instant = Instant.ofEpochMilli(2687940 * 1_000L) +shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe true + traceLocation.isAfterEndTime(instant) shouldBe false } +} +} - @Test - fun eventHasMalformedData() = runBlockingTest { - shouldThrow<InvalidQRCodeDataException> { - traceLocationQRCodeVerifier.verify( - INVALID_ENCODED_EVENT.decodeBase32().toByteArray() - ) - } +@Test +fun verifyEventEndTimeWarning() = runBlockingTest { +val instant = Instant.now() +shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe false + traceLocation.isAfterEndTime(instant) shouldBe true } +} +} + +@Test +fun verifyEventWithInvalidKey() = runBlockingTest { +every { environmentSetup.appConfigVerificationKey } returns INVALID_PUB_KEY +shouldThrow<InvalidQRCodeSignatureException> { + traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) +} +} - @Test - fun decodingTest1() = runBlockingTest { - val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT1.decodeBase32().toByteArray() - ) - val expectedSignature = - "MEQCIGVKfqPF2851IrEyDeVMazlRnIzLX16H6r1TB37PRzjbAiBGP13ADQcbQZsztKUCZMRcvnv5Mgdo0LY/v3qFMnrUkQ==" +@Test +fun eventHasMalformedData() = runBlockingTest { +shouldThrow<InvalidQRCodeDataException> { + traceLocationQRCodeVerifier.verify( + INVALID_ENCODED_EVENT.decodeBase32().toByteArray() + ) +} +} - val base32 = signedTraceLocation.toByteArray().toByteString().base32() +@Test +fun decodingTest1() = runBlockingTest { +val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT1.decodeBase32().toByteArray() +) +val expectedSignature = + "MEQCIGVKfqPF2851IrEyDeVMazlRnIzLX16H6r1TB37PRzjbAiBGP13ADQcbQZsztKUCZMRcvnv5Mgdo0LY/v3qFMnrUkQ==" - shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) +val base32 = signedTraceLocation.toByteArray().toByteString().base32() - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature - } - } +shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) + + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature } +} +} - @Test - fun decodingTest2() = runBlockingTest { - val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT2.decodeBase32().toByteArray() - ) - val expectedSignature = - "MEQCIDWRTM4ujn1GFPuHlgpUnQIWwwzwI8abxSrF5Er2I5HaAiAbucxg+6d3nC/Iwzo7AXehJAS20TRX1S2rl0LO8kcYxA==" +@Test +fun decodingTest2() = runBlockingTest { +val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT2.decodeBase32().toByteArray() +) +val expectedSignature = + "MEQCIDWRTM4ujn1GFPuHlgpUnQIWwwzwI8abxSrF5Er2I5HaAiAbucxg+6d3nC/Iwzo7AXehJAS20TRX1S2rl0LO8kcYxA==" - val base32 = signedTraceLocation.toByteArray().toByteString().base32() +val base32 = signedTraceLocation.toByteArray().toByteString().base32() - shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) +shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "Icecream Shop" - signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature - } - } + verifyResult.apply { + traceLocation.description shouldBe "Icecream Shop" + signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature } +} +} + +@Test +fun testVerifiedTraceLocationMapping() { +shouldNotThrowAny { + val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT1.decodeBase32().toByteArray() + ) + + val traceLocation = TraceLocationOuterClass.TraceLocation.parseFrom( + ENCODED_EVENT1_LOCATION.decodeBase32().toByteArray() + ) + val verifiedTraceLocation = VerifiedTraceLocation( + protoSignedTraceLocation = signedTraceLocation, + protoTraceLocation = traceLocation + ).traceLocation + + verifiedTraceLocation shouldBe TraceLocation( + guid = "3055331c-2306-43f3-9742-6d8fab54e848", + version = 1, + type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, + description = "My Birthday Party", + address = "at my place", + startDate = Instant.ofEpochSecond(2687955), + endDate = Instant.ofEpochSecond(2687991), + defaultCheckInLengthInMinutes = 0, + byteRepresentation = signedTraceLocation.location.toByteArray().toByteString(), + signature = signedTraceLocation.signature.toByteArray().toByteString() + ) +} +} - /* disabled because of incompatibilities due to tech spec changes... needs to be re-written anyway - - @Test - fun testVerifiedTraceLocationMapping() { - shouldNotThrowAny { - val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT1.decodeBase32().toByteArray() - ) - - val traceLocation = TraceLocationOuterClass.TraceLocation.parseFrom( - ENCODED_EVENT1_LOCATION.decodeBase32().toByteArray() - ) - val verifiedTraceLocation = VerifiedTraceLocation( - protoSignedTraceLocation = signedTraceLocation, - protoTraceLocation = traceLocation - ).traceLocation - - verifiedTraceLocation shouldBe TraceLocation( - guid = "3055331c-2306-43f3-9742-6d8fab54e848", - version = 1, - type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, - description = "My Birthday Party", - address = "at my place", - startDate = Instant.ofEpochSecond(2687955), - endDate = Instant.ofEpochSecond(2687991), - defaultCheckInLengthInMinutes = 0, - byteRepresentation = signedTraceLocation.location.toByteArray().toByteString(), - signature = signedTraceLocation.signature.toByteArray().toByteString() - ) - } - } - */ companion object { @@ -248,3 +223,5 @@ class VerifiedTraceLocationTest : BaseTestInstrumentation() { "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc7DEstcUIRcyk35OYDJ95/hTg3UVhsaDXKT0zK7NhHPXoyzipEnOp3GyNXDVpaPi3cAfQmxeuFMZAIX2+6A5Xg==" } } + + */ diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt index c1cf6775e3737a07adecde6046b7cd6b7fcbefaa..ee256cba854d7f0b96cb3e3e7b23470579639b1c 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt @@ -2,7 +2,6 @@ package de.rki.coronawarnapp.eventregistration.storage import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import okio.ByteString.Companion.toByteString import org.joda.time.Instant object CheckInDatabaseData { @@ -16,8 +15,6 @@ object CheckInDatabaseData { traceLocationStart = Instant.parse("2021-01-01T12:00:00.000Z"), traceLocationEnd = Instant.parse("2021-01-01T15:00:00.000Z"), defaultCheckInLengthInMinutes = 15, - traceLocationBytesBase64 = "", - signatureBase64 = "Signature".toByteArray().toByteString().base64(), checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"), checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"), completed = false, @@ -33,8 +30,6 @@ object CheckInDatabaseData { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytesBase64 = "", - signatureBase64 = "Signature".toByteArray().toByteString().base64(), checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"), checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"), completed = false, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt index b7d480c9b2256fcbc222af9ee67d61b25705b53c..431ec9f8b72e2830b41093706c26ecd6042fe6e4 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt @@ -3,7 +3,6 @@ package de.rki.coronawarnapp.eventregistration.checkins import com.google.protobuf.ByteString.copyFromUtf8 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity import de.rki.coronawarnapp.util.HashExtensions.toSHA256 -import okio.ByteString import org.joda.time.Instant @Suppress("LongParameterList") @@ -17,8 +16,6 @@ data class CheckIn( val traceLocationStart: Instant?, val traceLocationEnd: Instant?, val defaultCheckInLengthInMinutes: Int?, - val traceLocationBytes: ByteString, - val signature: ByteString, val checkInStart: Instant, val checkInEnd: Instant, val completed: Boolean, @@ -37,8 +34,6 @@ fun CheckIn.toEntity() = TraceLocationCheckInEntity( traceLocationStart = traceLocationStart, traceLocationEnd = traceLocationEnd, defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes, - traceLocationBytesBase64 = traceLocationBytes.base64(), - signatureBase64 = signature.base64(), checkInStart = checkInStart, checkInEnd = checkInEnd, completed = completed, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformer.kt index 5600923b4bf4c2ec02b62bc51a40e650a64488c8..6f76b0b04c1c86b8894e7ec7182343b834dbb2ab 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformer.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformer.kt @@ -5,7 +5,6 @@ import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.eventregistration.checkins.derivetime.deriveTime import de.rki.coronawarnapp.eventregistration.checkins.split.splitByMidnightUTC import de.rki.coronawarnapp.server.protocols.internal.pt.CheckInOuterClass -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.TransmissionRiskValueMapping import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.task.TransmissionRiskVector @@ -88,13 +87,8 @@ class CheckInsTransformer @Inject constructor( return null // Not mapped } - val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.newBuilder() - .setLocation(traceLocationBytes.toProtoByteString()) - .setSignature(signature.toProtoByteString()) - .build() - return CheckInOuterClass.CheckIn.newBuilder() - .setSignedLocation(signedTraceLocation) + // .locationId = TODO: Set calculated trace location .setStartIntervalNumber(checkInStart.derive10MinutesInterval().toInt()) .setEndIntervalNumber(checkInEnd.derive10MinutesInterval().toInt()) .setTransmissionRiskLevel(transmissionRiskLevel) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/download/TraceTimeIntervalWarningRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/download/TraceTimeIntervalWarningRepository.kt index 10319cca8599705be53688df0a9f47fa4d0c4d54..70a8d633266b300d12a2f6ac76d52a4f7c63d2c5 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/download/TraceTimeIntervalWarningRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/download/TraceTimeIntervalWarningRepository.kt @@ -1,7 +1,6 @@ package de.rki.coronawarnapp.eventregistration.checkins.download import de.rki.coronawarnapp.server.protocols.internal.pt.TraceWarning -import de.rki.coronawarnapp.util.HashExtensions.toSHA256 import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import org.joda.time.Duration @@ -42,7 +41,6 @@ object DummyCheckInPackage : TraceTimeIntervalWarningPackage { val warnings = (1L..1000L).map { createWarning( - traceLocationGuid = it.toString(), startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -50,12 +48,11 @@ val warnings = (1L..1000L).map { } fun createWarning( - traceLocationGuid: String, startIntervalDateStr: String, period: Int, transmissionRiskLevel: Int ) = TraceWarning.TraceTimeIntervalWarning.newBuilder() - .setLocationGuidHash(com.google.protobuf.ByteString.copyFromUtf8(traceLocationGuid.toSHA256())) + // .locationIdHash = TODO: set location Id hash .setPeriod(period) .setStartIntervalNumber((Duration(Instant.parse(startIntervalDateStr).millis).standardMinutes / 10).toInt()) .setTransmissionRiskLevel(transmissionRiskLevel) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParser.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParser.kt index 736e5f358bbb0e829203a44289a196a02c8fb0a7..7d622c3425e2e986c9117edf50e179940ea1ecde 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParser.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParser.kt @@ -15,7 +15,7 @@ class QRCodeUriParser @Inject constructor() { * https://e.coronawarn.app/c1/SIGNED_TRACE_LOCATION_BASE32 * HTTPS://E.CORONAWARN.APP/C1/SIGNED_TRACE_LOCATION_BASE32 */ - fun getSignedTraceLocation(maybeUri: String): ByteString? = URI.create(maybeUri).run { + fun getQrCodePayload(maybeUri: String): ByteString? = URI.create(maybeUri).run { if (!scheme.equals(SCHEME, true)) return@run null if (!authority.equals(AUTHORITY, true)) return@run null diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/TraceLocationQRCodeVerifier.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/TraceLocationQRCodeVerifier.kt deleted file mode 100644 index b04a7e1b693a874d0d8a6905e4baac28bf81cd32..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/TraceLocationQRCodeVerifier.kt +++ /dev/null @@ -1,44 +0,0 @@ -package de.rki.coronawarnapp.eventregistration.checkins.qrcode - -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.util.security.SignatureValidation -import timber.log.Timber -import javax.inject.Inject - -class TraceLocationQRCodeVerifier @Inject constructor( - private val signatureValidation: SignatureValidation -) { - - fun verify(rawTraceLocation: ByteArray): VerifiedTraceLocation { - Timber.v("Verifying: %s", rawTraceLocation) - - val signedTraceLocation = try { - TraceLocationOuterClass.SignedTraceLocation.parseFrom(rawTraceLocation) - } catch (e: Exception) { - throw InvalidQRCodeDataException(cause = e, message = "QR-code data could not be parsed.") - } - Timber.d("Parsed to signed location: %s", signedTraceLocation) - - val isValid = try { - signatureValidation.hasValidSignature( - signedTraceLocation.location.toByteArray(), - sequenceOf(signedTraceLocation.signature.toByteArray()) - ) - } catch (e: Exception) { - throw InvalidQRCodeDataException(cause = e, message = "Verification failed.") - } - - if (!isValid) { - throw InvalidQRCodeSignatureException(message = "QR-code did not match signature.") - } - - val traceLocation = TraceLocationOuterClass.TraceLocation.parseFrom( - signedTraceLocation.location - ) - - return VerifiedTraceLocation( - protoSignedTraceLocation = signedTraceLocation, - protoTraceLocation = traceLocation - ) - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt index 93f40d8d6dfd56ae70b0c5cc96d7fb9c9cddd517..40d43c74519fe4c334d6a5ec1829c4ff5fd38b80 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt @@ -7,40 +7,33 @@ import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parceler import kotlinx.parcelize.Parcelize import kotlinx.parcelize.TypeParceler -import okio.ByteString -import okio.ByteString.Companion.encode import okio.ByteString.Companion.toByteString import org.joda.time.Instant import java.util.concurrent.TimeUnit @Parcelize -@TypeParceler<TraceLocationOuterClass.SignedTraceLocation, SignedTraceLocationParceler>() @TypeParceler<TraceLocationOuterClass.TraceLocation, TraceLocationParceler>() +@TypeParceler<TraceLocationOuterClass.QRCodePayload, QrCodePayloadParceler>() data class VerifiedTraceLocation( - private val protoSignedTraceLocation: TraceLocationOuterClass.SignedTraceLocation, - private val protoTraceLocation: TraceLocationOuterClass.TraceLocation + private val protoQrCodePayload: TraceLocationOuterClass.QRCodePayload ) : Parcelable { - val traceLocationBytes: ByteString - get() = protoSignedTraceLocation.location.toByteArray().toByteString() - - val signature: ByteString - get() = protoSignedTraceLocation.signature.toByteArray().toByteString() + @IgnoredOnParcel private val vendorData by lazy { + TraceLocationOuterClass.CWALocationData.parseFrom(protoQrCodePayload.vendorData) + } @IgnoredOnParcel val traceLocation: TraceLocation by lazy { + TraceLocation( - // guid = protoTraceLocation.guid, - version = protoTraceLocation.version, - type = protoTraceLocation.type, - description = protoTraceLocation.description, - address = protoTraceLocation.address, - startDate = protoTraceLocation.startTimestamp.toInstant(), - endDate = protoTraceLocation.endTimestamp.toInstant(), - defaultCheckInLengthInMinutes = protoTraceLocation.defaultCheckInLengthInMinutes, - // byteRepresentation = traceLocationBytes, - // signature = signature, - cryptographicSeed = "".encode(), - cnPublicKey = "" + version = protoQrCodePayload.version, + type = vendorData.type, + description = protoQrCodePayload.locationData.description, + address = protoQrCodePayload.locationData.address, + startDate = protoQrCodePayload.locationData.startTimestamp.toInstant(), + endDate = protoQrCodePayload.locationData.endTimestamp.toInstant(), + defaultCheckInLengthInMinutes = vendorData.defaultCheckInLengthInMinutes, + cryptographicSeed = protoQrCodePayload.crowdNotifierData.cryptographicSeed.toByteArray().toByteString(), + cnPublicKey = protoQrCodePayload.crowdNotifierData.publicKey.toStringUtf8() ) } @@ -51,20 +44,6 @@ data class VerifiedTraceLocation( if (this == 0L) null else Instant.ofEpochMilli(TimeUnit.SECONDS.toMillis(this)) } -private object SignedTraceLocationParceler : Parceler<TraceLocationOuterClass.SignedTraceLocation> { - override fun create(parcel: Parcel): TraceLocationOuterClass.SignedTraceLocation { - val rawSignedTraceLocation = ByteArray(parcel.readInt()) - parcel.readByteArray(rawSignedTraceLocation) - return TraceLocationOuterClass.SignedTraceLocation.parseFrom(rawSignedTraceLocation) - } - - override fun TraceLocationOuterClass.SignedTraceLocation.write(parcel: Parcel, flags: Int) { - val rawSignedTraceLocation = toByteArray() - parcel.writeInt(rawSignedTraceLocation.size) - parcel.writeByteArray(rawSignedTraceLocation) - } -} - private object TraceLocationParceler : Parceler<TraceLocationOuterClass.TraceLocation> { override fun create(parcel: Parcel): TraceLocationOuterClass.TraceLocation { val rawTraceLocation = ByteArray(parcel.readInt()) @@ -78,3 +57,17 @@ private object TraceLocationParceler : Parceler<TraceLocationOuterClass.TraceLoc parcel.writeByteArray(rawTraceLocation) } } + +private object QrCodePayloadParceler : Parceler<TraceLocationOuterClass.QRCodePayload> { + override fun create(parcel: Parcel): TraceLocationOuterClass.QRCodePayload { + val rawSignedTraceLocation = ByteArray(parcel.readInt()) + parcel.readByteArray(rawSignedTraceLocation) + return TraceLocationOuterClass.QRCodePayload.parseFrom(rawSignedTraceLocation) + } + + override fun TraceLocationOuterClass.QRCodePayload.write(parcel: Parcel, flags: Int) { + val rawSignedTraceLocation = toByteArray() + parcel.writeInt(rawSignedTraceLocation.size) + parcel.writeByteArray(rawSignedTraceLocation) + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt index a287ba5537c5317684847fc22dc156807a45051d..8417c4df12009eb0c3e75e5092487421ef85610b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt @@ -4,7 +4,6 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import de.rki.coronawarnapp.eventregistration.checkins.CheckIn -import okio.ByteString.Companion.decodeBase64 import org.joda.time.Instant @Entity(tableName = "checkin") @@ -18,8 +17,6 @@ data class TraceLocationCheckInEntity( @ColumnInfo(name = "traceLocationStart") val traceLocationStart: Instant?, @ColumnInfo(name = "traceLocationEnd") val traceLocationEnd: Instant?, @ColumnInfo(name = "defaultCheckInLengthInMinutes") val defaultCheckInLengthInMinutes: Int?, - @ColumnInfo(name = "traceLocationBytesBase64") val traceLocationBytesBase64: String, - @ColumnInfo(name = "signatureBase64") val signatureBase64: String, @ColumnInfo(name = "checkInStart") val checkInStart: Instant, @ColumnInfo(name = "checkInEnd") val checkInEnd: Instant, @ColumnInfo(name = "completed") val completed: Boolean, @@ -36,8 +33,6 @@ fun TraceLocationCheckInEntity.toCheckIn() = CheckIn( traceLocationStart = traceLocationStart, traceLocationEnd = traceLocationEnd, defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes, - traceLocationBytes = traceLocationBytesBase64.decodeBase64()!!, - signature = signatureBase64.decodeBase64()!!, checkInStart = checkInStart, checkInEnd = checkInEnd, completed = completed, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt index 9a80e53107e1329cf26a87468f3f06343eaa2136..ea28693fca1bc08bb96b25b08a9668a8c112d37a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt @@ -117,7 +117,7 @@ internal fun CheckIn.calculateOverlap( traceWarningPackageId: String ): CheckInWarningOverlap? { - if (warning.locationGuidHash != locationGuidHash) return null + if (warning.locationIdHash != locationGuidHash) return null val warningStartTimestamp = warning.startIntervalNumber.tenMinIntervalToMillis() val warningEndTimestamp = (warning.startIntervalNumber + warning.period).tenMinIntervalToMillis() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt index 6e6a21591be207ee8d878c89cccd9fd62fabf8dc..4cffe352110e2ac18795c745c9b951ee181def75 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt @@ -8,11 +8,13 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository +import de.rki.coronawarnapp.eventregistration.checkins.qrcode.InvalidQRCodeDataException import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeUriParser -import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationQRCodeVerifier +import de.rki.coronawarnapp.eventregistration.checkins.qrcode.VerifiedTraceLocation import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.presencetracing.checkins.checkout.CheckOutHandler +import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.ActiveCheckInVH import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CameraPermissionVH import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CheckInsItem @@ -33,7 +35,6 @@ class CheckInsViewModel @AssistedInject constructor( @Assisted private val deepLink: String?, dispatcherProvider: DispatcherProvider, @AppScope private val appScope: CoroutineScope, - private val traceLocationQRCodeVerifier: TraceLocationQRCodeVerifier, private val qrCodeUriParser: QRCodeUriParser, private val checkInsRepository: CheckInRepository, private val checkOutHandler: CheckOutHandler, @@ -132,12 +133,17 @@ class CheckInsViewModel @AssistedInject constructor( private fun verifyUri(uri: String) = launch { try { Timber.i("uri: $uri") - val signedTraceLocation = qrCodeUriParser.getSignedTraceLocation(uri) + val qrCodePayloadRaw = qrCodeUriParser.getQrCodePayload(uri)?.toByteArray() ?: throw IllegalArgumentException("Invalid uri: $uri") - val verifyResult = traceLocationQRCodeVerifier.verify(signedTraceLocation.toByteArray()) - Timber.i("verifyResult: $verifyResult") - events.postValue(CheckInEvent.ConfirmCheckIn(verifyResult)) + val qrCodePayload = try { + TraceLocationOuterClass.QRCodePayload.parseFrom(qrCodePayloadRaw) + } catch (e: Exception) { + throw InvalidQRCodeDataException(cause = e, message = "QR-code data could not be parsed.") + } + + val verifiedTraceLocation = VerifiedTraceLocation(qrCodePayload) + events.postValue(CheckInEvent.ConfirmCheckIn(verifiedTraceLocation)) } catch (e: Exception) { Timber.d(e, "TraceLocation verification failed") e.report(ExceptionCategory.INTERNAL) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt index ba77ca1bc358fe2fcec52924c0a7b06d2e228160..3451c004c226aa60274ce3c6e0d9833c0b622624 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt @@ -89,8 +89,6 @@ class ConfirmCheckInViewModel @AssistedInject constructor( completed: Boolean = false, createJournalEntry: Boolean = true ): CheckIn = CheckIn( - traceLocationBytes = traceLocationBytes, - signature = signature, guid = "", // traceLocation.id, version = traceLocation.version, type = traceLocation.type.number, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt index 5d5ccca4ddbd3d5b7333ea8d9ad942f52321edef..46fe74481bf8e6f3b97efd699517a3ae72797f7b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString.Companion.EMPTY import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -55,8 +54,6 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = Instant.EPOCH, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = EMPTY, - signature = EMPTY, checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH, completed = false, @@ -83,8 +80,6 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = time, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = EMPTY, - signature = EMPTY, checkInStart = time, checkInEnd = end, completed = false, @@ -103,8 +98,6 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = time, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytesBase64 = "", - signatureBase64 = "", checkInStart = time, checkInEnd = end, completed = false, @@ -147,8 +140,6 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = start, traceLocationEnd = end, defaultCheckInLengthInMinutes = null, - traceLocationBytesBase64 = "", - signatureBase64 = "", checkInStart = start, checkInEnd = end, completed = false, @@ -160,7 +151,6 @@ class CheckInRepositoryTest : BaseTest() { CheckIn( id = 1L, guid = "6e5530ce-1afc-4695-a4fc-572e6443eacd", - traceLocationBytes = EMPTY, version = 1, type = 2, description = "sisters birthday", @@ -168,7 +158,6 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = start, traceLocationEnd = end, defaultCheckInLengthInMinutes = null, - signature = EMPTY, checkInStart = start, checkInEnd = end, completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt index 552744e41ce95279c0dabafe5cdc8bc76b477786..00a7739a2bf7d64a66045044ffba2d7e74245049 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt @@ -2,8 +2,6 @@ package de.rki.coronawarnapp.eventregistration.checkins import de.rki.coronawarnapp.submission.task.TransmissionRiskVector import io.kotest.matchers.shouldBe -import okio.ByteString.Companion.EMPTY -import okio.ByteString.Companion.decodeBase64 import org.joda.time.Instant import org.junit.jupiter.api.Test import testhelpers.BaseTest @@ -20,8 +18,6 @@ class CheckInTransmissionRiskLevelTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = EMPTY, - signature = "c2lnbmF0dXJlMQ==".decodeBase64()!!, checkInStart = Instant.parse("2021-03-04T10:20:00Z"), checkInEnd = Instant.parse("2021-03-04T10:30:00Z"), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt index 9b41e3a0dfb183b01996f1c0d281de2577102aea..f242f86a79bca66ec32d715e0b7511fff67fc25a 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt @@ -7,8 +7,8 @@ import de.rki.coronawarnapp.appconfig.PresenceTracingConfigContainer import de.rki.coronawarnapp.appconfig.PresenceTracingRiskCalculationParamContainer import de.rki.coronawarnapp.appconfig.PresenceTracingSubmissionParamContainer import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.server.protocols.internal.v2.PresenceTracingParametersOuterClass.PresenceTracingSubmissionParameters.DurationFilter import de.rki.coronawarnapp.server.protocols.internal.v2.PresenceTracingParametersOuterClass.PresenceTracingSubmissionParameters.AerosoleDecayFunctionLinear +import de.rki.coronawarnapp.server.protocols.internal.v2.PresenceTracingParametersOuterClass.PresenceTracingSubmissionParameters.DurationFilter import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.Range import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.TransmissionRiskValueMapping import de.rki.coronawarnapp.submission.Symptoms @@ -23,8 +23,6 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString.Companion.EMPTY -import okio.ByteString.Companion.decodeBase64 import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -50,8 +48,6 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = EMPTY, - signature = "c2lnbmF0dXJlMQ==".decodeBase64()!!, checkInStart = Instant.parse("2021-03-04T10:21:00Z"), checkInEnd = Instant.parse("2021-03-04T10:29:00Z"), completed = false, @@ -74,8 +70,6 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = TRACE_LOCATION_2.decodeBase64()!!, - signature = "c2lnbmF0dXJlMQ==".decodeBase64()!!, checkInStart = Instant.parse("2021-03-04T10:20:00Z"), checkInEnd = Instant.parse("2021-03-04T10:30:00Z"), completed = false, @@ -93,8 +87,6 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = Instant.parse("2021-03-04T09:00:00Z"), traceLocationEnd = Instant.parse("2021-03-10T11:00:00Z"), defaultCheckInLengthInMinutes = 10, - traceLocationBytes = TRACE_LOCATION_3.decodeBase64()!!, - signature = "c2lnbmF0dXJlMQ==".decodeBase64()!!, checkInStart = Instant.parse("2021-03-04T09:30:00Z"), checkInEnd = Instant.parse("2021-03-10T09:45:00Z"), completed = false, @@ -222,7 +214,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-04T10:20:00Z").seconds / TEN_MINUTES_IN_SECONDS // New derived end time endIntervalNumber shouldBe Instant.parse("2021-03-04T10:40:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_2" version shouldBe 1 @@ -233,7 +225,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe 0 defaultCheckInLengthInMinutes shouldBe 0 transmissionRiskLevel shouldBe 1 - } + }*/ } // Check-In 3 mappings and transformation @@ -262,7 +254,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-04T09:30:00Z").seconds / TEN_MINUTES_IN_SECONDS // End time for splitted check-in 1 endIntervalNumber shouldBe Instant.parse("2021-03-05T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_3" version shouldBe 1 @@ -273,7 +265,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe Instant.parse("2021-03-10T11:00:00Z").seconds defaultCheckInLengthInMinutes shouldBe 10 transmissionRiskLevel shouldBe 1 - } + }*/ } // Splitted CheckIn 2 @@ -282,7 +274,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-05T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS // End time for splitted check-in 2 endIntervalNumber shouldBe Instant.parse("2021-03-06T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_3" version shouldBe 1 @@ -293,7 +285,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe Instant.parse("2021-03-10T11:00:00Z").seconds defaultCheckInLengthInMinutes shouldBe 10 transmissionRiskLevel shouldBe 1 - } + }*/ } // Splitted CheckIn 3 @@ -302,7 +294,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-06T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS // End time for splitted check-in 3 endIntervalNumber shouldBe Instant.parse("2021-03-07T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_3" version shouldBe 1 @@ -313,7 +305,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe Instant.parse("2021-03-10T11:00:00Z").seconds defaultCheckInLengthInMinutes shouldBe 10 transmissionRiskLevel shouldBe 2 - } + }*/ } // Splitted CheckIn 4 @@ -322,7 +314,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-07T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS // End time for splitted check-in 4 endIntervalNumber shouldBe Instant.parse("2021-03-08T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_3" version shouldBe 1 @@ -333,7 +325,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe Instant.parse("2021-03-10T11:00:00Z").seconds defaultCheckInLengthInMinutes shouldBe 10 transmissionRiskLevel shouldBe 4 - } + }*/ } // Splitted CheckIn 5 @@ -342,7 +334,7 @@ class CheckInsTransformerTest : BaseTest() { startIntervalNumber shouldBe Instant.parse("2021-03-10T00:00:00Z").seconds / TEN_MINUTES_IN_SECONDS // End time for splitted check-in 5 endIntervalNumber shouldBe Instant.parse("2021-03-10T10:20:00Z").seconds / TEN_MINUTES_IN_SECONDS - signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) + /*signedLocation.signature shouldBe ByteString.copyFrom("signature1".toByteArray()) parseLocation(signedLocation.location).apply { guid shouldBe "trace_location_3" version shouldBe 1 @@ -353,7 +345,7 @@ class CheckInsTransformerTest : BaseTest() { endTimestamp shouldBe Instant.parse("2021-03-10T11:00:00Z").seconds defaultCheckInLengthInMinutes shouldBe 10 transmissionRiskLevel shouldBe 8 - } + }*/ } } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultQRCodeVerifierTest2.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultQRCodeVerifierTest2.kt index ca6eecac1bb333a477a89d9166d1a7904652be40..5a767d467dcc7696076c8e28082bf2f79dee8074 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultQRCodeVerifierTest2.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultQRCodeVerifierTest2.kt @@ -1,14 +1,12 @@ package de.rki.coronawarnapp.eventregistration.checkins.qrcode -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.util.decodeBase32 -import io.kotest.matchers.shouldBe -import okio.ByteString.Companion.toByteString -import org.junit.jupiter.api.Test import testhelpers.BaseTest class DefaultQRCodeVerifierTest2 : BaseTest() { + /* Disabled, because new protobuf doesn't include signed traceLocation, we should write tests for the parsing of + QrCodePayload protobuf ... + @Test fun `protobuf decoding 1`() { val signedTraceLocation = @@ -61,4 +59,6 @@ class DefaultQRCodeVerifierTest2 : BaseTest() { signedTraceLocation.location.toByteArray().toByteString() .base64() shouldBe "CiRmY2E4NGIzNy02MWMwLTRhN2MtYjJmOC04MjVjYWRkNTA2Y2YQARgBIg1JY2VjcmVhbSBTaG9wKg1NYWluIFN0cmVldCAxMAA4AEAK" } + + */ } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParserTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParserTest.kt index 27a0d286f206191f06d00681e03a92c4ee06982d..71a1c8722df6ebbcae83bb335bebdd1176f56d30 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParserTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/QRCodeUriParserTest.kt @@ -13,12 +13,12 @@ class QRCodeUriParserTest : BaseTest() { @ParameterizedTest @ArgumentsSource(ValidUrlProvider::class) fun `Valid URLs`(input: String) { - createInstance().getSignedTraceLocation(input) shouldNotBe null + createInstance().getQrCodePayload(input) shouldNotBe null } @ParameterizedTest @ArgumentsSource(InvalidUrlProvider::class) fun `Invalid URLs`(input: String) { - createInstance().getSignedTraceLocation(input) shouldBe null + createInstance().getQrCodePayload(input) shouldBe null } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt index 47cde34c371f17308c710a226079f073951a0de7..0e3e7ebc06f4511bc8242b4873def4250dccd03f 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt @@ -2,11 +2,8 @@ package de.rki.coronawarnapp.eventregistration.checkins.split import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import io.kotest.matchers.shouldBe -import okio.ByteString.Companion.EMPTY -import okio.ByteString.Companion.decodeBase64 import org.joda.time.Instant import org.junit.jupiter.api.Test - import testhelpers.BaseTest /** @@ -25,8 +22,6 @@ class CheckInSplitterTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = EMPTY, - signature = "c2lnbmF0dXJl".decodeBase64()!!, checkInStart = Instant.now(), checkInEnd = Instant.now(), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/TraceLocationData.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/TraceLocationData.kt deleted file mode 100644 index e7c760cab05502aeaab53fd336f7ab87719296a5..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/TraceLocationData.kt +++ /dev/null @@ -1,40 +0,0 @@ -package de.rki.coronawarnapp.eventregistration.events.server - -import de.rki.coronawarnapp.eventregistration.events.TraceLocationUserInput -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds -import org.joda.time.Instant - -object TraceLocationData { - - val traceLocationTemporaryUserInput = TraceLocationUserInput( - type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, - description = "Event Registration Release Party", - address = "SAP Headquarter", - startDate = Instant.parse("2021-05-01T19:00:00.000Z"), - endDate = Instant.parse("2021-05-01T23:30:00.000Z"), - defaultCheckInLengthInMinutes = 180 - ) - - private val traceLocationTemporary: TraceLocationOuterClass.TraceLocation = - TraceLocationOuterClass.TraceLocation.newBuilder() - .setGuid("serverGeneratedGuid") - .setVersion(1) - .setType(TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER) - .setDescription("Event Registration Release Party") - .setAddress("SAP Headquarter") - .setStartTimestamp(Instant.parse("2021-05-01T19:00:00.000Z").seconds) - .setEndTimestamp(Instant.parse("2021-05-01T23:30:00.000Z").seconds) - .setDefaultCheckInLengthInMinutes(180) - .build() - - private val traceLocationPermanent: TraceLocationOuterClass.TraceLocation = - TraceLocationOuterClass.TraceLocation.newBuilder() - .setGuid("serverGeneratedGuid") - .setVersion(1) - .setType(TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_OTHER) - .setDescription("IceCream Shop") - .setAddress("IceCream Wonderland Street 1") - .setDefaultCheckInLengthInMinutes(30) - .build() -} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt index 94bac736a528831a4e243dd9725be5a0752746eb..844daabd845b2af29a69183d73e3edb48132c5b5 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt @@ -12,7 +12,6 @@ import io.mockk.impl.annotations.MockK import io.mockk.just import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString.Companion.toByteString import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -78,8 +77,6 @@ internal class CheckInCleanerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = 30, - traceLocationBytes = "".toByteArray().toByteString(), - signature = "".toByteArray().toByteString(), // checkInStart not relevant for this that's, checkInStart = Instant.parse("1970-01-01T00:00:00.000Z"), checkInEnd = checkOutDate, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt index df80096d69c0043201a33741a5ff85562b7d4bb7..80d421ca9503ca4f442c4e1ee7718ee645465b2c 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt @@ -10,8 +10,6 @@ import io.mockk.coEvery import io.mockk.every import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString -import okio.ByteString.Companion.toByteString import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -33,8 +31,6 @@ class CheckOutHandlerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = ByteString.EMPTY, - signature = "signature".toByteArray().toByteString(), checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH.plus(100), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt index 19f69da2fd47d6587c8689f989da9099bedf283f..0dfb7658ad8b740401a259db7b43215320f9ae6f 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runBlockingTest -import okio.ByteString import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -45,8 +44,6 @@ class AutoCheckOutTest : BaseTest() { traceLocationStart = Instant.EPOCH, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = ByteString.EMPTY, - signature = ByteString.EMPTY, checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH, completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt index 96180e4ada99e3805da440514a45046544e4a864..c417f1a01b99d5969edc8bb66bb6eb3198ad0c1b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt @@ -49,14 +49,14 @@ class CheckInWarningMatcherTest : BaseTest() { ) val warning1 = createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 ) val warning2 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -98,14 +98,14 @@ class CheckInWarningMatcherTest : BaseTest() { ) val warning1 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 ) val warning2 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -170,14 +170,14 @@ class CheckInWarningMatcherTest : BaseTest() { fun `deletes all matches if no check-ins`() { val warning1 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 ) val warning2 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -215,7 +215,7 @@ class CheckInWarningMatcherTest : BaseTest() { } val warnings = (1L..1000L).map { createWarning( - traceLocationGuid = it.toString(), + traceLocationId = it.toString(), startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt index 054622727df104fd95febddc628df950c0d9b2ff..03c384f2ecfd471fcca4006b788ca36daae7269c 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt @@ -24,14 +24,14 @@ class FindMatchesTest { ) val warning1 = createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:30+01:00", period = 6, transmissionRiskLevel = 8 ) val warning2 = createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T15:30+01:00", period = 6, transmissionRiskLevel = 8 diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt index aa84b1b06fbb7719a90dc6bc41c1c1f6505a0dc1..59f57bfc73a67e3480c937d31786a7a2c2996221 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt @@ -5,7 +5,6 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import de.rki.coronawarnapp.server.protocols.internal.pt.TraceWarning import de.rki.coronawarnapp.util.HashExtensions.toSHA256 import io.kotest.matchers.shouldBe -import okio.ByteString import org.joda.time.Duration import org.joda.time.Instant import org.junit.Test @@ -23,7 +22,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T09:45+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -40,7 +39,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T09:45+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -57,7 +56,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T11:20+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -74,7 +73,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:00+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -91,7 +90,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T11:10+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -108,7 +107,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:12+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -125,7 +124,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T11:12+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -142,7 +141,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:13+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -159,7 +158,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:17+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -176,7 +175,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T11:00+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -193,7 +192,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T11:00+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -210,7 +209,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:05:45+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -227,7 +226,7 @@ class OverlapTest : BaseTest() { endDateStr = "2021-03-04T10:05:15+01:00" ).calculateOverlap( createWarning( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startIntervalDateStr = "2021-03-04T10:00+01:00", period = 6, transmissionRiskLevel = 8 @@ -252,8 +251,6 @@ fun createCheckIn( traceLocationStart = Instant.parse(startDateStr), traceLocationEnd = null, defaultCheckInLengthInMinutes = null, - traceLocationBytes = ByteString.EMPTY, - signature = ByteString.EMPTY, checkInStart = Instant.parse(startDateStr), checkInEnd = Instant.parse(endDateStr), completed = false, @@ -261,12 +258,12 @@ fun createCheckIn( ) fun createWarning( - traceLocationGuid: String, + traceLocationId: String, startIntervalDateStr: String, period: Int, transmissionRiskLevel: Int ) = TraceWarning.TraceTimeIntervalWarning.newBuilder() - .setLocationGuidHash(copyFromUtf8(traceLocationGuid.toSHA256())) + .setLocationIdHash(copyFromUtf8(traceLocationId.toSHA256())) .setPeriod(period) .setStartIntervalNumber((Duration(Instant.parse(startIntervalDateStr).millis).standardMinutes / 10).toInt()) .setTransmissionRiskLevel(transmissionRiskLevel) diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/server/SubmissionServerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/server/SubmissionServerTest.kt index 10e5149bbef59e404ad4c89602fbd959f3a72791..d20cb37bafa6ce162736c4f25282fe36d7a7b820 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/server/SubmissionServerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/server/SubmissionServerTest.kt @@ -10,9 +10,7 @@ import de.rki.coronawarnapp.http.HttpModule import de.rki.coronawarnapp.server.protocols.external.exposurenotification.TemporaryExposureKeyExportOuterClass import de.rki.coronawarnapp.server.protocols.internal.SubmissionPayloadOuterClass import de.rki.coronawarnapp.server.protocols.internal.pt.CheckInOuterClass -import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass -import de.rki.coronawarnapp.server.protocols.internal.v2.PresenceTracingParametersOuterClass - .PresenceTracingPlausibleDeniabilityParameters.NumberOfFakeCheckInsFunctionParameters +import de.rki.coronawarnapp.server.protocols.internal.v2.PresenceTracingParametersOuterClass.PresenceTracingPlausibleDeniabilityParameters.NumberOfFakeCheckInsFunctionParameters import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass import de.rki.coronawarnapp.submission.SubmissionModule import de.rki.coronawarnapp.util.headerSizeIgnoringContentLength @@ -28,7 +26,6 @@ import kotlinx.coroutines.runBlocking import okhttp3.ConnectionSpec import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer -import okio.ByteString.Companion.decodeBase64 import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -77,18 +74,9 @@ class SubmissionServerTest : BaseTest() { @Test fun `genuine submission - empty checkInPadding`(): Unit = runBlocking { val testKeyData = ByteString.copyFrom("TestKeyDataGoogle", Charsets.UTF_8) - val signedTraceLocation = ByteString.copyFrom( - "ChB0cmFjZV9sb2NhdGlvbl8zEAEYAyIMcmVzdGF1cmFudF8zKglhZGRyZXNzXzMwkMOCggY4sMGNggZACg==" - .decodeBase64()!!.toByteArray() - ) val checkIn = CheckInOuterClass.CheckIn.newBuilder() .setEndIntervalNumber(0) .setStartIntervalNumber(0) - .setSignedLocation( - TraceLocationOuterClass.SignedTraceLocation.parseFrom( - signedTraceLocation - ) - ) .build() val server = createServer() @@ -154,18 +142,9 @@ class SubmissionServerTest : BaseTest() { ) } val testKeyData = ByteString.copyFrom("TestKeyDataGoogle", Charsets.UTF_8) - val signedTraceLocation = ByteString.copyFrom( - "ChB0cmFjZV9sb2NhdGlvbl8zEAEYAyIMcmVzdGF1cmFudF8zKglhZGRyZXNzXzMwkMOCggY4sMGNggZACg==" - .decodeBase64()!!.toByteArray() - ) val checkIn = CheckInOuterClass.CheckIn.newBuilder() .setEndIntervalNumber(0) .setStartIntervalNumber(0) - .setSignedLocation( - TraceLocationOuterClass.SignedTraceLocation.parseFrom( - signedTraceLocation - ) - ) .build() val server = createServer() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt index 5aa94ee55c8a6c1403c2425fac94265b9f4176a3..77d37b6285bcc0b9d4981ce580d366e7440d0ed8 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.SavedStateHandle import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeUriParser -import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationQRCodeVerifier import de.rki.coronawarnapp.presencetracing.checkins.checkout.CheckOutHandler import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.ActiveCheckInVH import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CameraPermissionVH @@ -38,7 +37,6 @@ import testhelpers.extensions.getOrAwaitValue class CheckInsViewModelTest : BaseTest() { @MockK lateinit var savedState: SavedStateHandle - @MockK lateinit var traceLocationQRCodeVerifier: TraceLocationQRCodeVerifier @MockK lateinit var qrCodeUriParser: QRCodeUriParser @MockK lateinit var checkInsRepository: CheckInRepository @MockK lateinit var checkOutHandler: CheckOutHandler @@ -82,15 +80,13 @@ class CheckInsViewModelTest : BaseTest() { @Test fun `DeepLink verification`() = runBlockingTest { every { savedState.get<String>(any()) } returns null - every { qrCodeUriParser.getSignedTraceLocation(any()) } returns ByteString.EMPTY - every { traceLocationQRCodeVerifier.verify(any()) } returns mockk() + every { qrCodeUriParser.getQrCodePayload(any()) } returns ByteString.EMPTY createInstance(deepLink = DEEP_LINK, scope = this).apply { events.getOrAwaitValue().shouldBeInstanceOf<CheckInEvent.ConfirmCheckIn>() verify { savedState.get<String>(any()) - qrCodeUriParser.getSignedTraceLocation(any()) - traceLocationQRCodeVerifier.verify(any()) + qrCodeUriParser.getQrCodePayload(any()) savedState.set(any(), any<String>()) } } @@ -185,7 +181,6 @@ class CheckInsViewModelTest : BaseTest() { deepLink = deepLink, dispatcherProvider = TestDispatcherProvider(), appScope = scope, - traceLocationQRCodeVerifier = traceLocationQRCodeVerifier, qrCodeUriParser = qrCodeUriParser, checkInsRepository = checkInsRepository, checkOutHandler = checkOutHandler, diff --git a/Server-Protocol-Buffer/src/main/proto/internal/pt/check_in.proto b/Server-Protocol-Buffer/src/main/proto/internal/pt/check_in.proto index 6f809744639b23ec376a36683c832a6c0265675b..cb96a68d144d3bfdfb92965fb839f6a2c17d9b40 100644 --- a/Server-Protocol-Buffer/src/main/proto/internal/pt/check_in.proto +++ b/Server-Protocol-Buffer/src/main/proto/internal/pt/check_in.proto @@ -2,11 +2,10 @@ syntax = "proto3"; package de.rki.coronawarnapp.server.protocols.internal.pt; -import "internal/pt/trace_location.proto"; message CheckIn { - SignedTraceLocation signedLocation = 1; + bytes locationId = 1; uint32 startIntervalNumber = 2; uint32 endIntervalNumber = 3; uint32 transmissionRiskLevel = 4; -} \ No newline at end of file +} diff --git a/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_location.proto b/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_location.proto index b0c1dd5088de6c90869661e041a6b20de425366c..baf364df29eddd47d9dde80956f7b884b7225a20 100644 --- a/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_location.proto +++ b/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_location.proto @@ -2,26 +2,31 @@ syntax = "proto3"; package de.rki.coronawarnapp.server.protocols.internal.pt; +message QRCodePayload { + uint32 version = 1; + TraceLocation locationData = 2; + CrowdNotifierData crowdNotifierData = 3; + // byte sequence of CWALocationData + bytes vendorData = 4; +} message TraceLocation { - // uuid - string guid = 1; - uint32 version = 2; - TraceLocationType type = 3; - // max. 150 characters - string description = 4; - // max. 150 characters - string address = 5; + uint32 version = 1; + // max. 100 characters + string description = 2; + // max. 100 characters + string address = 3; + // UNIX timestamp (in seconds) - uint64 startTimestamp = 6; + uint64 startTimestamp = 5; // UNIX timestamp (in seconds) - uint64 endTimestamp = 7; - uint32 defaultCheckInLengthInMinutes = 8; + uint64 endTimestamp = 6; } -message SignedTraceLocation { - bytes location = 1; - bytes signature = 2; +message CrowdNotifierData { + uint32 version = 1; + bytes publicKey = 2; + bytes cryptographicSeed = 3; } enum TraceLocationType { @@ -41,4 +46,10 @@ enum TraceLocationType { LOCATION_TYPE_TEMPORARY_PRIVATE_EVENT = 11; LOCATION_TYPE_TEMPORARY_WORSHIP_SERVICE = 12; +} + +message CWALocationData { + uint32 version = 1; + TraceLocationType type = 2; + uint32 defaultCheckInLengthInMinutes = 3; } \ No newline at end of file diff --git a/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_warning.proto b/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_warning.proto index e6df1c6bdb5476552e7017aabea2a3e5896363c5..7ecd2da3aa52b9777ca8dc434f08e37e63858be1 100644 --- a/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_warning.proto +++ b/Server-Protocol-Buffer/src/main/proto/internal/pt/trace_warning.proto @@ -3,8 +3,6 @@ syntax = "proto3"; package de.rki.coronawarnapp.server.protocols.internal.pt; -import "internal/pt/check_in.proto"; - message TraceWarningPackage { // hours since UNIX Epoch uint32 intervalNumber = 1; @@ -13,7 +11,7 @@ message TraceWarningPackage { } message TraceTimeIntervalWarning { - bytes locationGuidHash = 1; // Hash of the Location GUID + bytes locationIdHash = 1; // SHA-256 of the Location ID // 10-minute intervals since UNIX Epoch uint32 startIntervalNumber = 2; // Number of 10-minute intervals to which the warning applies diff --git a/Server-Protocol-Buffer/src/main/proto/internal/v2/presence_tracing_parameters.proto b/Server-Protocol-Buffer/src/main/proto/internal/v2/presence_tracing_parameters.proto index f04206bf0399845d71f79b5913cd20a8de7dec21..da8eb8be4527fa4883cb4e17855b4389be6fbc23 100644 --- a/Server-Protocol-Buffer/src/main/proto/internal/v2/presence_tracing_parameters.proto +++ b/Server-Protocol-Buffer/src/main/proto/internal/v2/presence_tracing_parameters.proto @@ -80,11 +80,11 @@ message PresenceTracingQRCodeDescriptor { string regexPattern = 1; uint32 versionGroupIndex = 2; - uint32 encodedTraceLocationGroupIndex = 3; + uint32 encodedPayloadGroupIndex = 3; - TraceLocationEncoding traceLocationEncoding = 4; + PayloadEncoding payloadEncoding = 4; - enum TraceLocationEncoding { + enum PayloadEncoding { BASE32 = 0; BASE64 = 1; }