diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/CoronaTestModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/CoronaTestModule.kt
index b4295fc63485450d62cca4ca0ddcdd2552c533fe..1445d927e4f2eed79b3ba219c0708249eb33ee07 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/CoronaTestModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/CoronaTestModule.kt
@@ -5,8 +5,8 @@ import dagger.Module
 import dagger.multibindings.IntoSet
 import de.rki.coronawarnapp.coronatest.server.VerificationModule
 import de.rki.coronawarnapp.coronatest.type.CoronaTestProcessor
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRProcessor
-import de.rki.coronawarnapp.coronatest.type.rapidantigen.RAProcessor
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRTestProcessor
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RATestProcessor
 
 @Module(
     includes = [VerificationModule::class]
@@ -16,12 +16,12 @@ abstract class CoronaTestModule {
     @Binds
     @IntoSet
     abstract fun pcrProcessor(
-        processor: PCRProcessor
+        processor: PCRTestProcessor
     ): CoronaTestProcessor
 
     @Binds
     @IntoSet
     abstract fun ratProcessor(
-        processor: RAProcessor
+        processor: RATestProcessor
     ): CoronaTestProcessor
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/TestCertificateRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/TestCertificateRepository.kt
index 6bd544343d2ae905da542d56284f30a4ec755340..b50985a1d33607cb1ee978e3a63c8ce8e530d8d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/TestCertificateRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/TestCertificateRepository.kt
@@ -1,44 +1,30 @@
 package de.rki.coronawarnapp.coronatest
 
-import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.bugreporting.reportProblem
 import de.rki.coronawarnapp.coronatest.storage.TestCertificateStorage
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.TestCertificateWrapper
 import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
 import de.rki.coronawarnapp.coronatest.type.common.TestCertificateIdentifier
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateContainer
-import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateContainer
-import de.rki.coronawarnapp.covidcertificate.exception.InvalidHealthCertificateException.ErrorCode.RSA_DECRYPTION_FAILED
-import de.rki.coronawarnapp.covidcertificate.exception.InvalidHealthCertificateException.ErrorCode.RSA_KP_GENERATION_FAILED
-import de.rki.coronawarnapp.covidcertificate.exception.InvalidTestCertificateException
-import de.rki.coronawarnapp.covidcertificate.exception.TestCertificateServerException
-import de.rki.coronawarnapp.covidcertificate.exception.TestCertificateServerException.ErrorCode.DCC_COMP_202
-import de.rki.coronawarnapp.covidcertificate.server.CovidCertificateServer
-import de.rki.coronawarnapp.covidcertificate.server.TestCertificateComponents
+import de.rki.coronawarnapp.coronatest.type.common.TestCertificateProcessor
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateData
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
-import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
-import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
-import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
 import de.rki.coronawarnapp.util.flow.HotDataFlow
 import de.rki.coronawarnapp.util.flow.combine
 import de.rki.coronawarnapp.util.mutate
 import de.rki.coronawarnapp.vaccination.core.repository.ValueSetsRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.plus
 import kotlinx.coroutines.withContext
-import okio.ByteString.Companion.decodeBase64
-import org.joda.time.Duration
 import timber.log.Timber
 import java.util.UUID
 import javax.inject.Inject
@@ -49,14 +35,10 @@ import javax.inject.Singleton
 class TestCertificateRepository @Inject constructor(
     @AppScope private val appScope: CoroutineScope,
     private val dispatcherProvider: DispatcherProvider,
-    private val timeStamper: TimeStamper,
     private val storage: TestCertificateStorage,
-    private val certificateServer: CovidCertificateServer,
-    private val rsaKeyPairGenerator: RSAKeyPairGenerator,
-    private val rsaCryptography: RSACryptography,
     private val qrCodeExtractor: TestCertificateQRCodeExtractor,
-    private val appConfigProvider: AppConfigProvider,
-    private val valueSetsRepository: ValueSetsRepository,
+    private val processor: TestCertificateProcessor,
+    valueSetsRepository: ValueSetsRepository,
 ) {
 
     private val internalData: HotDataFlow<Map<TestCertificateIdentifier, TestCertificateContainer>> = HotDataFlow(
@@ -64,9 +46,17 @@ class TestCertificateRepository @Inject constructor(
         scope = appScope + dispatcherProvider.Default,
         sharingBehavior = SharingStarted.Eagerly,
     ) {
-        storage.testCertificates.map { it.identifier to it }.toMap().also {
-            Timber.tag(TAG).v("Restored TestCertificate data: %s", it)
-        }
+        storage.testCertificates
+            .map {
+                TestCertificateContainer(
+                    data = it,
+                    qrCodeExtractor = qrCodeExtractor
+                )
+            }
+            .map { it.identifier to it }
+            .toMap().also {
+                Timber.tag(TAG).v("Restored TestCertificate data: %s", it)
+            }
     }
 
     val certificates: Flow<Set<TestCertificateWrapper>> = combine(
@@ -84,9 +74,10 @@ class TestCertificateRepository @Inject constructor(
     init {
         internalData.data
             .onStart { Timber.tag(TAG).d("Observing TestCertificateContainer data.") }
-            .onEach {
-                Timber.tag(TAG).v("TestCertificateContainer data changed: %s", it)
-                storage.testCertificates = it.values.toSet()
+            .onEach { entrySets ->
+                val values = entrySets.values
+                Timber.tag(TAG).v("TestCertificateContainer data changed: %s", values)
+                storage.testCertificates = values.map { it.data }.toSet()
             }
             .catch {
                 it.reportProblem(TAG, "Failed to snapshot TestCertificateContainer data to storage.")
@@ -119,22 +110,24 @@ class TestCertificateRepository @Inject constructor(
 
             val identifier = UUID.randomUUID().toString()
 
-            val certificate = when (test.type) {
-                CoronaTest.Type.PCR -> PCRCertificateContainer(
+            val data = when (test.type) {
+                CoronaTest.Type.PCR -> PCRCertificateData(
                     identifier = identifier,
                     registeredAt = test.registeredAt,
                     registrationToken = test.registrationToken,
                 )
-                CoronaTest.Type.RAPID_ANTIGEN -> RACertificateContainer(
+                CoronaTest.Type.RAPID_ANTIGEN -> RACertificateData(
                     identifier = identifier,
                     registeredAt = test.registeredAt,
                     registrationToken = test.registrationToken,
                 )
-            }.also {
-                it.qrCodeExtractor = qrCodeExtractor
             }
-            Timber.tag(TAG).d("Adding test certificate entry: %s", certificate)
-            mutate { this[certificate.identifier] = certificate }
+            val container = TestCertificateContainer(
+                data = data,
+                qrCodeExtractor = qrCodeExtractor,
+            )
+            Timber.tag(TAG).d("Adding test certificate entry: %s", container)
+            mutate { this[container.identifier] = container }
         }
 
         return newData.values.single { it.registrationToken == test.registrationToken }
@@ -175,10 +168,7 @@ class TestCertificateRepository @Inject constructor(
             mutate {
                 toRefresh.forEach {
                     workedOnIds.add(it.identifier)
-                    this[it.identifier] = when (it.type) {
-                        CoronaTest.Type.PCR -> (it as PCRCertificateContainer).copy(isUpdatingData = true)
-                        CoronaTest.Type.RAPID_ANTIGEN -> (it as RACertificateContainer).copy(isUpdatingData = true)
-                    }
+                    this[it.identifier] = it.copy(isUpdatingData = false)
                 }
             }
         }
@@ -192,7 +182,8 @@ class TestCertificateRepository @Inject constructor(
                 .map { cert ->
                     withContext(dispatcherProvider.IO) {
                         try {
-                            RefreshResult(registerPublicKey(cert))
+                            val updatedData = processor.registerPublicKey(cert.data)
+                            RefreshResult(cert.copy(data = updatedData))
                         } catch (e: Exception) {
                             Timber.tag(TAG).e(e, "Failed to register public key for %s", cert)
                             RefreshResult(cert, e)
@@ -221,7 +212,8 @@ class TestCertificateRepository @Inject constructor(
                 .map { cert ->
                     withContext(dispatcherProvider.IO) {
                         try {
-                            RefreshResult(obtainCertificate(cert))
+                            val updatedData = processor.obtainCertificate(cert.data)
+                            RefreshResult(cert.copy(data = updatedData))
                         } catch (e: Exception) {
                             Timber.tag(TAG).e(e, "Failed to retrieve certificate components for %s", cert)
                             RefreshResult(cert, e)
@@ -246,10 +238,7 @@ class TestCertificateRepository @Inject constructor(
 
             mutate {
                 certs.forEach {
-                    this[it.identifier] = when (it.type) {
-                        CoronaTest.Type.PCR -> (it as PCRCertificateContainer).copy(isUpdatingData = false)
-                        CoronaTest.Type.RAPID_ANTIGEN -> (it as RACertificateContainer).copy(isUpdatingData = false)
-                    }
+                    this[it.identifier] = it.copy(isUpdatingData = false)
                 }
             }
         }
@@ -257,125 +246,6 @@ class TestCertificateRepository @Inject constructor(
         return refreshCallResults.values.toSet()
     }
 
-    /**
-     * Register the public key with the server, a shortwhile later,
-     * the test certificate components should be available, via [obtainCertificate].
-     */
-    private suspend fun registerPublicKey(
-        cert: TestCertificateContainer
-    ): TestCertificateContainer {
-        Timber.tag(TAG).d("registerPublicKey(cert=%s)", cert)
-
-        if (cert.isPublicKeyRegistered) {
-            Timber.tag(TAG).d("Public key is already registered for %s", cert)
-            return cert
-        }
-
-        val rsaKeyPair = try {
-            rsaKeyPairGenerator.generate()
-        } catch (e: Throwable) {
-            throw InvalidTestCertificateException(RSA_KP_GENERATION_FAILED)
-        }
-
-        certificateServer.registerPublicKeyForTest(
-            testRegistrationToken = cert.registrationToken,
-            publicKey = rsaKeyPair.publicKey,
-        )
-        Timber.tag(TAG).i("Public key successfully registered for %s", cert)
-
-        val nowUTC = timeStamper.nowUTC
-
-        return when (cert.type) {
-            CoronaTest.Type.PCR -> (cert as PCRCertificateContainer).copy(
-                publicKeyRegisteredAt = nowUTC,
-                rsaPublicKey = rsaKeyPair.publicKey,
-                rsaPrivateKey = rsaKeyPair.privateKey,
-            )
-            CoronaTest.Type.RAPID_ANTIGEN -> (cert as RACertificateContainer).copy(
-                publicKeyRegisteredAt = nowUTC,
-                rsaPublicKey = rsaKeyPair.publicKey,
-                rsaPrivateKey = rsaKeyPair.privateKey,
-            )
-        }
-    }
-
-    /**
-     * Try to obtain the actual certificate.
-     * PublicKey registration and certificate retrieval are two steps, because if we manage to register our public key,
-     * but fail to get the certificate, we are still one step further.
-     *
-     * The server does not immediately return the test certificate components after registering the public key.
-     */
-    private suspend fun obtainCertificate(
-        cert: TestCertificateContainer
-    ): TestCertificateContainer {
-        Timber.tag(TAG).d("requestCertificate(cert=%s)", cert)
-
-        if (!cert.isPublicKeyRegistered) throw IllegalStateException("Public key is not registered yet.")
-
-        if (!cert.isCertificateRetrievalPending) {
-            Timber.tag(TAG).d("Dcc has already been retrieved for %s", cert)
-            return cert
-        }
-
-        val certConfig = appConfigProvider.currentConfig.first().covidCertificateParameters.testCertificate
-
-        val nowUTC = timeStamper.nowUTC
-        val certAvailableAt = cert.publicKeyRegisteredAt!!.plus(certConfig.waitAfterPublicKeyRegistration)
-        val certAvailableIn = Duration(nowUTC, certAvailableAt)
-
-        if (certAvailableIn > Duration.ZERO && certAvailableIn <= certConfig.waitAfterPublicKeyRegistration) {
-            Timber.tag(TAG).d("Delaying certificate retrieval by %d ms", certAvailableIn.millis)
-            delay(certAvailableIn.millis)
-        }
-
-        val executeRequest: suspend () -> TestCertificateComponents = {
-            certificateServer.requestCertificateForTest(testRegistrationToken = cert.registrationToken)
-        }
-
-        val components = try {
-            executeRequest()
-        } catch (e: TestCertificateServerException) {
-            if (e.errorCode == DCC_COMP_202) {
-                delay(certConfig.waitForRetry.millis)
-                executeRequest()
-            } else {
-                throw e
-            }
-        }
-        Timber.tag(TAG).i("Test certificate components successfully request for %s: %s", cert, components)
-
-        val encryptionKey = try {
-            rsaCryptography.decrypt(
-                toDecrypt = components.dataEncryptionKeyBase64.decodeBase64()!!,
-                privateKey = cert.rsaPrivateKey!!
-            )
-        } catch (e: Throwable) {
-            Timber.tag(TAG).e(e, "RSA_DECRYPTION_FAILED")
-            throw InvalidTestCertificateException(RSA_DECRYPTION_FAILED)
-        }
-
-        val extractedData = qrCodeExtractor.extract(
-            decryptionKey = encryptionKey.toByteArray(),
-            rawCoseObjectEncrypted = components.encryptedCoseTestCertificateBase64.decodeBase64()!!.toByteArray()
-        )
-
-        val nowUtc = timeStamper.nowUTC
-
-        return when (cert.type) {
-            CoronaTest.Type.PCR -> (cert as PCRCertificateContainer).copy(
-                testCertificateQrCode = extractedData.qrCode,
-                certificateReceivedAt = nowUtc,
-            )
-            CoronaTest.Type.RAPID_ANTIGEN -> (cert as RACertificateContainer).copy(
-                testCertificateQrCode = extractedData.qrCode,
-                certificateReceivedAt = nowUtc,
-            )
-        }.also {
-            it.preParsedData = extractedData.testCertificateData
-        }
-    }
-
     /**
      * [deleteCertificate] does not throw an exception, if the deletion target already does not exist.
      */
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorage.kt
index e6933d9507986a097e0554706f737dbe547aff5a..c56688b65a75b9250475acd91bd5be14c64ed68e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorage.kt
@@ -6,9 +6,9 @@ import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import de.rki.coronawarnapp.coronatest.server.CoronaTestResult
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
-import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateContainer
-import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateContainer
+import de.rki.coronawarnapp.coronatest.type.common.StoredTestCertificateData
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateData
 import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import de.rki.coronawarnapp.vaccination.core.repository.storage.ContainerPostProcessor
@@ -35,29 +35,29 @@ class TestCertificateStorage @Inject constructor(
     }
 
     private val typeTokenPCR by lazy {
-        object : TypeToken<Set<PCRCertificateContainer>>() {}.type
+        object : TypeToken<Set<PCRCertificateData>>() {}.type
     }
 
     private val typeTokenRA by lazy {
-        object : TypeToken<Set<RACertificateContainer>>() {}.type
+        object : TypeToken<Set<RACertificateData>>() {}.type
     }
 
-    var testCertificates: Collection<TestCertificateContainer>
+    var testCertificates: Collection<StoredTestCertificateData>
         get() {
             Timber.tag(TAG).d("load()")
 
-            val pcrCertContainers: Set<PCRCertificateContainer> = run {
+            val pcrCertContainers: Set<PCRCertificateData> = run {
                 val raw = prefs.getString(PKEY_DATA_PCR, null) ?: return@run emptySet()
-                gson.fromJson<Set<PCRCertificateContainer>>(raw, typeTokenPCR).onEach {
+                gson.fromJson<Set<PCRCertificateData>>(raw, typeTokenPCR).onEach {
                     Timber.tag(TAG).v("PCR loaded: %s", it)
                     requireNotNull(it.identifier)
                     requireNotNull(it.type) { "PCR type should not be null, GSON footgun." }
                 }
             }
 
-            val raCerts: Set<RACertificateContainer> = run {
+            val raCerts: Set<RACertificateData> = run {
                 val raw = prefs.getString(PKEY_DATA_RA, null) ?: return@run emptySet()
-                gson.fromJson<Set<RACertificateContainer>>(raw, typeTokenRA).onEach {
+                gson.fromJson<Set<RACertificateData>>(raw, typeTokenRA).onEach {
                     Timber.tag(TAG).v("RA loaded: %s", it)
                     requireNotNull(it.identifier)
                     requireNotNull(it.type) { "RA type should not be null, GSON footgun." }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/StoredTestCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/StoredTestCertificateData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..70234ef8c25fd69b8cb7b23ff0abc2f2417a1460
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/StoredTestCertificateData.kt
@@ -0,0 +1,21 @@
+package de.rki.coronawarnapp.coronatest.type.common
+
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.RegistrationToken
+import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
+import okio.ByteString
+import org.joda.time.Instant
+
+interface StoredTestCertificateData {
+    val identifier: TestCertificateIdentifier
+    val registrationToken: RegistrationToken
+    val type: CoronaTest.Type
+    val registeredAt: Instant
+    val publicKeyRegisteredAt: Instant?
+    val rsaPublicKey: RSAKey.Public?
+    val rsaPrivateKey: RSAKey.Private?
+    val certificateReceivedAt: Instant?
+    val encryptedDataEncryptionkey: ByteString?
+    val encryptedDccCose: ByteString?
+    val testCertificateQrCode: String?
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateContainer.kt
index f49ffb3d09f42e9af6f2823a07fcb007a2b2a0ce..13f2b62f62feb65d337d210081aa9b937b68fe63 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateContainer.kt
@@ -1,51 +1,32 @@
 package de.rki.coronawarnapp.coronatest.type.common
 
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
-import de.rki.coronawarnapp.coronatest.type.RegistrationToken
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificate
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateData
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
-import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import de.rki.coronawarnapp.vaccination.core.CertificatePersonIdentifier
 import de.rki.coronawarnapp.vaccination.core.personIdentifier
 import de.rki.coronawarnapp.vaccination.core.qrcode.QrCodeString
 import de.rki.coronawarnapp.vaccination.core.server.valueset.valuesets.TestCertificateValueSets
-import okio.ByteString
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import java.util.Locale
 
-abstract class TestCertificateContainer {
-    abstract val identifier: TestCertificateIdentifier
-    abstract val registrationToken: RegistrationToken
-    abstract val type: CoronaTest.Type
-    abstract val registeredAt: Instant
-    abstract val publicKeyRegisteredAt: Instant?
-    abstract val rsaPublicKey: RSAKey.Public?
-    abstract val rsaPrivateKey: RSAKey.Private?
-    abstract val certificateReceivedAt: Instant?
-    abstract val encryptedDataEncryptionkey: ByteString?
-    abstract val encryptedDccCose: ByteString?
-    abstract val testCertificateQrCode: String?
-
-    abstract val isUpdatingData: Boolean
-
-    // Either set by [ContainerPostProcessor] (if from storage) or during first creation (when new)
-    @Transient internal lateinit var qrCodeExtractor: TestCertificateQRCodeExtractor
-
-    // When we create this container initially, we don't need to pare the data again, we already have it.
-    @Transient internal var preParsedData: TestCertificateData? = null
+data class TestCertificateContainer(
+    internal val data: StoredTestCertificateData,
+    private val qrCodeExtractor: TestCertificateQRCodeExtractor,
+    val isUpdatingData: Boolean = false,
+) : StoredTestCertificateData by data {
 
     @delegate:Transient
     private val certificateData: TestCertificateData by lazy {
-        preParsedData ?: testCertificateQrCode!!.let { qrCodeExtractor.extract(it).testCertificateData }
+        data.testCertificateQrCode!!.let { qrCodeExtractor.extract(it).testCertificateData }
     }
 
     val isPublicKeyRegistered: Boolean
-        get() = publicKeyRegisteredAt != null
+        get() = data.publicKeyRegisteredAt != null
 
     val isCertificateRetrievalPending: Boolean
-        get() = certificateReceivedAt == null
+        get() = data.certificateReceivedAt == null
 
     val certificateId: String?
         get() {
@@ -108,9 +89,7 @@ abstract class TestCertificateContainer {
                 get() = header.expiresAt
 
             override val qrCode: QrCodeString
-                get() = testCertificateQrCode!!
+                get() = data.testCertificateQrCode!!
         }
     }
 }
-
-typealias TestCertificateIdentifier = String
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateIdentifier.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateIdentifier.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1c3642a39554921616e505a07100eadda8e83f82
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateIdentifier.kt
@@ -0,0 +1,3 @@
+package de.rki.coronawarnapp.coronatest.type.common
+
+typealias TestCertificateIdentifier = String
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2bf24175b2720966b49f07b0f62b3a5e95f9682c
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessor.kt
@@ -0,0 +1,158 @@
+package de.rki.coronawarnapp.coronatest.type.common
+
+import dagger.Reusable
+import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateData
+import de.rki.coronawarnapp.covidcertificate.exception.InvalidHealthCertificateException
+import de.rki.coronawarnapp.covidcertificate.exception.InvalidTestCertificateException
+import de.rki.coronawarnapp.covidcertificate.exception.TestCertificateServerException
+import de.rki.coronawarnapp.covidcertificate.server.CovidCertificateServer
+import de.rki.coronawarnapp.covidcertificate.server.TestCertificateComponents
+import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
+import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
+import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.first
+import okio.ByteString.Companion.decodeBase64
+import org.joda.time.Duration
+import timber.log.Timber
+import javax.inject.Inject
+
+@Reusable
+class TestCertificateProcessor @Inject constructor(
+    private val timeStamper: TimeStamper,
+    private val certificateServer: CovidCertificateServer,
+    private val rsaKeyPairGenerator: RSAKeyPairGenerator,
+    private val rsaCryptography: RSACryptography,
+    private val appConfigProvider: AppConfigProvider,
+    private val qrCodeExtractor: TestCertificateQRCodeExtractor,
+) {
+
+    /**
+     * Register the public key with the server, a shortwhile later,
+     * the test certificate components should be available, via [obtainCertificate].
+     */
+    internal suspend fun registerPublicKey(
+        data: StoredTestCertificateData
+    ): StoredTestCertificateData {
+        Timber.tag(TAG).d("registerPublicKey(cert=%s)", data)
+
+        if (data.publicKeyRegisteredAt != null) {
+            Timber.tag(TAG).d("Public key is already registered for %s", data)
+            return data
+        }
+
+        val rsaKeyPair = try {
+            rsaKeyPairGenerator.generate()
+        } catch (e: Throwable) {
+            throw InvalidTestCertificateException(InvalidHealthCertificateException.ErrorCode.RSA_KP_GENERATION_FAILED)
+        }
+
+        certificateServer.registerPublicKeyForTest(
+            testRegistrationToken = data.registrationToken,
+            publicKey = rsaKeyPair.publicKey,
+        )
+        Timber.tag(TAG).i("Public key successfully registered for %s", data)
+
+        val nowUTC = timeStamper.nowUTC
+
+        return when (data.type) {
+            CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(
+                publicKeyRegisteredAt = nowUTC,
+                rsaPublicKey = rsaKeyPair.publicKey,
+                rsaPrivateKey = rsaKeyPair.privateKey,
+            )
+            CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(
+                publicKeyRegisteredAt = nowUTC,
+                rsaPublicKey = rsaKeyPair.publicKey,
+                rsaPrivateKey = rsaKeyPair.privateKey,
+            )
+        }
+    }
+
+    /**
+     * Try to obtain the actual certificate.
+     * PublicKey registration and certificate retrieval are two steps, because if we manage to register our public key,
+     * but fail to get the certificate, we are still one step further.
+     *
+     * The server does not immediately return the test certificate components after registering the public key.
+     */
+    internal suspend fun obtainCertificate(
+        data: StoredTestCertificateData
+    ): StoredTestCertificateData {
+        Timber.tag(TAG).d("requestCertificate(cert=%s)", data)
+
+        if (data.publicKeyRegisteredAt == null) {
+            throw IllegalStateException("Public key is not registered yet.")
+        }
+
+        if (data.certificateReceivedAt != null) {
+            Timber.tag(TAG).d("Dcc has already been retrieved for %s", data)
+            return data
+        }
+
+        val certConfig = appConfigProvider.currentConfig.first().covidCertificateParameters.testCertificate
+
+        val nowUTC = timeStamper.nowUTC
+        val certAvailableAt = data.publicKeyRegisteredAt!!.plus(certConfig.waitAfterPublicKeyRegistration)
+        val certAvailableIn = Duration(nowUTC, certAvailableAt)
+
+        if (certAvailableIn > Duration.ZERO && certAvailableIn <= certConfig.waitAfterPublicKeyRegistration) {
+            Timber.tag(TAG)
+                .d("Delaying certificate retrieval by %d ms", certAvailableIn.millis)
+            delay(certAvailableIn.millis)
+        }
+
+        val executeRequest: suspend () -> TestCertificateComponents = {
+            certificateServer.requestCertificateForTest(testRegistrationToken = data.registrationToken)
+        }
+
+        val components = try {
+            executeRequest()
+        } catch (e: TestCertificateServerException) {
+            if (e.errorCode == TestCertificateServerException.ErrorCode.DCC_COMP_202) {
+                delay(certConfig.waitForRetry.millis)
+                executeRequest()
+            } else {
+                throw e
+            }
+        }
+        Timber.tag(TAG)
+            .i("Test certificate components successfully request for %s: %s", data, components)
+
+        val encryptionKey = try {
+            rsaCryptography.decrypt(
+                toDecrypt = components.dataEncryptionKeyBase64.decodeBase64()!!,
+                privateKey = data.rsaPrivateKey!!
+            )
+        } catch (e: Throwable) {
+            Timber.tag(TAG).e(e, "RSA_DECRYPTION_FAILED")
+            throw InvalidTestCertificateException(InvalidHealthCertificateException.ErrorCode.RSA_DECRYPTION_FAILED)
+        }
+
+        val extractedData = qrCodeExtractor.extract(
+            decryptionKey = encryptionKey.toByteArray(),
+            rawCoseObjectEncrypted = components.encryptedCoseTestCertificateBase64.decodeBase64()!!.toByteArray()
+        )
+
+        val nowUtc = timeStamper.nowUTC
+
+        return when (data.type) {
+            CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(
+                testCertificateQrCode = extractedData.qrCode,
+                certificateReceivedAt = nowUtc,
+            )
+            CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(
+                testCertificateQrCode = extractedData.qrCode,
+                certificateReceivedAt = nowUtc,
+            )
+        }
+    }
+
+    companion object {
+        private val TAG = TestCertificateProcessor::class.simpleName!!
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateData.kt
similarity index 87%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateContainer.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateData.kt
index bee0ea96cbe785f848431428613e264ab35fe997..148d5c5a87a61d8cdec492cfc6b9bbdef096d2d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCertificateData.kt
@@ -3,12 +3,12 @@ package de.rki.coronawarnapp.coronatest.type.pcr
 import com.google.gson.annotations.SerializedName
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.RegistrationToken
-import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
+import de.rki.coronawarnapp.coronatest.type.common.StoredTestCertificateData
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import okio.ByteString
 import org.joda.time.Instant
 
-data class PCRCertificateContainer internal constructor(
+data class PCRCertificateData internal constructor(
     @SerializedName("identifier")
     override val identifier: String,
 
@@ -38,9 +38,7 @@ data class PCRCertificateContainer internal constructor(
 
     @SerializedName("testCertificateQrCode")
     override val testCertificateQrCode: String? = null,
-
-    @Transient override val isUpdatingData: Boolean = false,
-) : TestCertificateContainer() {
+) : StoredTestCertificateData {
 
     // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null
     @Suppress("unused")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRTestProcessor.kt
similarity index 98%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRTestProcessor.kt
index b46f1f7ad3c5061673177472a5eb1e3f303fb1f6..58bfe8a28d16fd55ab3d07efd251fd7f4458e288 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRTestProcessor.kt
@@ -37,7 +37,7 @@ import timber.log.Timber
 import javax.inject.Inject
 
 @Reusable
-class PCRProcessor @Inject constructor(
+class PCRTestProcessor @Inject constructor(
     private val timeStamper: TimeStamper,
     private val submissionService: CoronaTestService,
     private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector,
@@ -277,7 +277,7 @@ private fun CoronaTestResult.toValidatedResult(): CoronaTestResult {
     return if (isValid) {
         this
     } else {
-        Timber.tag(PCRProcessor.TAG).e("Server returned invalid PCR testresult $this")
+        Timber.tag(PCRTestProcessor.TAG).e("Server returned invalid PCR testresult $this")
         PCR_INVALID
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateData.kt
similarity index 88%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateContainer.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateData.kt
index ccea190914256452f13550f07db1a32bbbbf2667..89f8cfaf368a9916ca7630a210fc5aff2149035c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACertificateData.kt
@@ -3,12 +3,12 @@ package de.rki.coronawarnapp.coronatest.type.rapidantigen
 import com.google.gson.annotations.SerializedName
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.RegistrationToken
-import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
+import de.rki.coronawarnapp.coronatest.type.common.StoredTestCertificateData
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import okio.ByteString
 import org.joda.time.Instant
 
-data class RACertificateContainer(
+data class RACertificateData(
     @SerializedName("identifier")
     override val identifier: String,
 
@@ -38,9 +38,7 @@ data class RACertificateContainer(
 
     @SerializedName("testCertificateQrCode")
     override val testCertificateQrCode: String? = null,
-
-    @Transient override val isUpdatingData: Boolean = false,
-) : TestCertificateContainer() {
+) : StoredTestCertificateData {
 
     // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null
     @Suppress("unused")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RATestProcessor.kt
similarity index 95%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RATestProcessor.kt
index 9f5364756fe00ed53dd92d27956e23bbc798a01f..075881497a8447e524264062768309f02867f60d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RATestProcessor.kt
@@ -21,7 +21,6 @@ import de.rki.coronawarnapp.coronatest.server.VerificationServer
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.CoronaTestProcessor
 import de.rki.coronawarnapp.coronatest.type.CoronaTestService
-import de.rki.coronawarnapp.coronatest.type.common.DateOfBirthKey
 import de.rki.coronawarnapp.coronatest.type.isOlderThan21Days
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.testresult.AnalyticsTestResultCollector
@@ -36,7 +35,7 @@ import timber.log.Timber
 import javax.inject.Inject
 
 @Reusable
-class RAProcessor @Inject constructor(
+class RATestProcessor @Inject constructor(
     private val timeStamper: TimeStamper,
     private val submissionService: CoronaTestService,
     private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector,
@@ -56,13 +55,9 @@ class RAProcessor @Inject constructor(
         analyticsKeySubmissionCollector.reset(type)
         analyticsTestResultCollector.clear(type)
 
-        val dateOfBirthKey = if (request.isDccConsentGiven && request.dateOfBirth != null) {
-            DateOfBirthKey(request.registrationIdentifier, request.dateOfBirth)
-        } else null
-
         val serverRequest = RegistrationRequest(
             key = request.registrationIdentifier,
-            dateOfBirthKey = dateOfBirthKey,
+            dateOfBirthKey = null,
             type = VerificationKeyType.GUID
         )
 
@@ -256,7 +251,7 @@ private fun CoronaTestResult.toValidatedResult(): CoronaTestResult {
     return if (isValid) {
         this
     } else {
-        Timber.tag(RAProcessor.TAG).e("Server returned invalid RapidAntigen testresult $this")
+        Timber.tag(RATestProcessor.TAG).e("Server returned invalid RapidAntigen testresult $this")
         RAT_INVALID
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateApiV1.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateApiV1.kt
index a8ec6a371d59184f11486848504ba2ea034d51ca..58f8f045aa7a1a5e7eae23106243b311593a58af 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateApiV1.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateApiV1.kt
@@ -37,5 +37,5 @@ interface CovidCertificateApiV1 {
     @POST("/version/v1/dcc")
     suspend fun getComponents(
         @Body requestBody: ComponentsRequest
-    ): Response<ComponentsResponse>
+    ): Response<ComponentsResponse?>
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateModule.kt
index 16ff646f69a824c39403da866ef1b6bb525d7aca..0cd432e90bfb0fda2fb2445449909204ad2ee6e5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/server/CovidCertificateModule.kt
@@ -6,24 +6,44 @@ import dagger.Reusable
 import de.rki.coronawarnapp.environment.covidcertificate.DCCHttpClient
 import de.rki.coronawarnapp.environment.covidcertificate.DCCServerUrl
 import okhttp3.OkHttpClient
+import okhttp3.ResponseBody
+import retrofit2.Converter
 import retrofit2.Retrofit
 import retrofit2.converter.gson.GsonConverterFactory
+import java.lang.reflect.Type
 
 @Module
 class CovidCertificateModule {
 
+    /**
+     * Handles DCC server 202 "retry later" response with 0-byte bodies.
+     */
+    private val nullConverter = object : Converter.Factory() {
+        fun factoryRef() = this
+        override fun responseBodyConverter(
+            type: Type,
+            annotations: Array<out Annotation>,
+            retrofit: Retrofit
+        ) = object : Converter<ResponseBody, Any?> {
+            val nextConverter = retrofit.nextResponseBodyConverter<Any?>(factoryRef(), type, annotations)
+
+            override fun convert(value: ResponseBody): Any? {
+                return if (value.contentLength() != 0L) nextConverter.convert(value) else null
+            }
+        }
+    }
+
     @Reusable
     @Provides
     fun apiV1(
         @DCCHttpClient httpClient: OkHttpClient,
         @DCCServerUrl url: String,
         gsonConverterFactory: GsonConverterFactory
-    ): CovidCertificateApiV1 {
-        return Retrofit.Builder()
-            .client(httpClient)
-            .baseUrl(url)
-            .addConverterFactory(gsonConverterFactory)
-            .build()
-            .create(CovidCertificateApiV1::class.java)
-    }
+    ): CovidCertificateApiV1 = Retrofit.Builder()
+        .client(httpClient)
+        .baseUrl(url)
+        .addConverterFactory(nullConverter)
+        .addConverterFactory(gsonConverterFactory)
+        .build()
+        .create(CovidCertificateApiV1::class.java)
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ContainerPostProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ContainerPostProcessor.kt
index 6278616309ca033daf51fac2731da3796a834d68..013f39609253a2eb7d58dc36fe130a2c4ecb6f2e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ContainerPostProcessor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ContainerPostProcessor.kt
@@ -7,8 +7,6 @@ import com.google.gson.reflect.TypeToken
 import com.google.gson.stream.JsonReader
 import com.google.gson.stream.JsonWriter
 import dagger.Reusable
-import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
-import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
 import de.rki.coronawarnapp.vaccination.core.qrcode.VaccinationQRCodeExtractor
 import timber.log.Timber
 import java.io.IOException
@@ -17,7 +15,6 @@ import javax.inject.Inject
 @Reusable
 class ContainerPostProcessor @Inject constructor(
     private val vaccinationQrCodeExtractor: VaccinationQRCodeExtractor,
-    private val testCertificateQRCodeExtractor: TestCertificateQRCodeExtractor,
 ) : TypeAdapterFactory {
     override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T> {
         val delegate = gson.getDelegateAdapter(this, type)
@@ -35,10 +32,6 @@ class ContainerPostProcessor @Inject constructor(
                         Timber.v("Injecting VaccinationContainer %s", obj.hashCode())
                         obj.qrCodeExtractor = vaccinationQrCodeExtractor
                     }
-                    is TestCertificateContainer -> {
-                        Timber.v("Injecting TestCertificateContainer %s", obj.hashCode())
-                        obj.qrCodeExtractor = testCertificateQRCodeExtractor
-                    }
                 }
 
                 return obj
diff --git a/Corona-Warn-App/src/main/res/xml/network_security_config.xml b/Corona-Warn-App/src/main/res/xml/network_security_config.xml
index 00fe5354674c0acbb34ef04bc1121c033c9a3200..ffbf5cd7d82d16014558eba526e7a54009f99789 100644
--- a/Corona-Warn-App/src/main/res/xml/network_security_config.xml
+++ b/Corona-Warn-App/src/main/res/xml/network_security_config.xml
@@ -1,14 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
-<network-security-config xmlns:tools="http://schemas.android.com/tools">
+<network-security-config>
 
     <domain-config cleartextTrafficPermitted="false">
         <domain includeSubdomains="true">coronawarn.app</domain>
         <domain includeSubdomains="true">main.px.t-online.de</domain>
-        <pin-set
-            expiration="2024-02-12"
-            tools:ignore="MissingBackupPin">
-            <pin digest="SHA-256">c3jf+L8VIAFQnJJDM6Mfb4MtI1JnhVS8JwZHMwJj28M=</pin>
-        </pin-set>
+        <!--        FIXME-->
+        <!--        <pin-set-->
+        <!--            expiration="2024-02-12"-->
+        <!--            tools:ignore="MissingBackupPin">-->
+        <!--            <pin digest="SHA-256">c3jf+L8VIAFQnJJDM6Mfb4MtI1JnhVS8JwZHMwJj28M=</pin>-->
+        <!--        </pin-set>-->
         <trust-anchors>
             <certificates
                 overridePins="false"
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestRepositoryTest.kt
index 267613b4ada2052a2b2e0e5086468ed12c2ba75e..7eb566a58f9810a6458f0c3499b0d2d6243e4a1a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestRepositoryTest.kt
@@ -6,9 +6,9 @@ import de.rki.coronawarnapp.coronatest.server.CoronaTestResult
 import de.rki.coronawarnapp.coronatest.storage.CoronaTestStorage
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRProcessor
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRTestProcessor
 import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest
-import de.rki.coronawarnapp.coronatest.type.rapidantigen.RAProcessor
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RATestProcessor
 import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.coEvery
@@ -38,9 +38,9 @@ class CoronaTestRepositoryTest : BaseTest() {
         registrationToken = "token",
         testResult = CoronaTestResult.PCR_REDEEMED,
     )
-    @MockK lateinit var pcrProcessor: PCRProcessor
+    @MockK lateinit var pcrProcessor: PCRTestProcessor
 
-    @MockK lateinit var raProcessor: RAProcessor
+    @MockK lateinit var raProcessor: RATestProcessor
     private val raTest = RACoronaTest(
         identifier = "ra-identifier",
         lastUpdatedAt = Instant.EPOCH,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateRepositoryTest.kt
index 2ba03c24600f54faf6e02011c4e6beef59b8a712..00b314260d2ebc0433ce37ca06254b9957680d5a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateRepositoryTest.kt
@@ -1,52 +1,35 @@
 package de.rki.coronawarnapp.coronatest
 
-import de.rki.coronawarnapp.appconfig.AppConfigProvider
-import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.appconfig.CovidCertificateConfig
 import de.rki.coronawarnapp.coronatest.storage.TestCertificateStorage
-import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateContainer
-import de.rki.coronawarnapp.covidcertificate.server.CovidCertificateServer
-import de.rki.coronawarnapp.covidcertificate.server.TestCertificateComponents
+import de.rki.coronawarnapp.coronatest.type.common.StoredTestCertificateData
+import de.rki.coronawarnapp.coronatest.type.common.TestCertificateProcessor
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCode
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
-import de.rki.coronawarnapp.util.TimeStamper
-import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
-import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
 import de.rki.coronawarnapp.vaccination.core.repository.ValueSetsRepository
 import io.mockk.MockKAnnotations
-import io.mockk.Runs
 import io.mockk.coEvery
-import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
-import io.mockk.just
 import io.mockk.mockk
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.emptyFlow
-import kotlinx.coroutines.flow.flowOf
-import okio.ByteString
 import org.joda.time.Duration
 import org.joda.time.Instant
 import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 import testhelpers.TestDispatcherProvider
-import testhelpers.coroutines.runBlockingTest2
 
 class TestCertificateRepositoryTest : BaseTest() {
 
-    @MockK lateinit var timeStamper: TimeStamper
     @MockK lateinit var storage: TestCertificateStorage
-    @MockK lateinit var certificateServer: CovidCertificateServer
-    @MockK lateinit var rsaCryptography: RSACryptography
     @MockK lateinit var qrCodeExtractor: TestCertificateQRCodeExtractor
-    @MockK lateinit var appConfigProvider: AppConfigProvider
-    @MockK lateinit var appConfigData: ConfigData
     @MockK lateinit var covidTestCertificateConfig: CovidCertificateConfig.TestCertificate
     @MockK lateinit var valueSetsRepository: ValueSetsRepository
+    @MockK lateinit var testCertificateProcessor: TestCertificateProcessor
 
-    private val testCertificateNew = PCRCertificateContainer(
+    private val testCertificateNew = PCRCertificateData(
         identifier = "identifier1",
         registrationToken = "regtoken1",
         registeredAt = Instant.EPOCH,
@@ -58,24 +41,12 @@ class TestCertificateRepositoryTest : BaseTest() {
         rsaPrivateKey = mockk(),
     )
 
-    private val testCerticateComponents = mockk<TestCertificateComponents>().apply {
-        every { dataEncryptionKeyBase64 } returns "dek"
-        every { encryptedCoseTestCertificateBase64 } returns ""
-    }
-
-    private var storageSet = mutableSetOf<TestCertificateContainer>()
+    private var storageSet = mutableSetOf<StoredTestCertificateData>()
 
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
 
-        every { timeStamper.nowUTC } returns Instant.EPOCH
-
-        every { appConfigProvider.currentConfig } returns flowOf(appConfigData)
-        every { appConfigData.covidCertificateParameters } returns mockk<CovidCertificateConfig>().apply {
-            every { testCertificate } returns covidTestCertificateConfig
-        }
-
         covidTestCertificateConfig.apply {
             every { waitForRetry } returns Duration.standardSeconds(10)
             every { waitAfterPublicKeyRegistration } returns Duration.standardSeconds(10)
@@ -89,13 +60,6 @@ class TestCertificateRepositoryTest : BaseTest() {
             every { storage.testCertificates } answers { storageSet }
         }
 
-        certificateServer.apply {
-            coEvery { registerPublicKeyForTest(any(), any()) } just Runs
-            coEvery { requestCertificateForTest(any()) } returns testCerticateComponents
-        }
-
-        every { rsaCryptography.decrypt(any(), any()) } returns ByteString.Companion.EMPTY
-
         coEvery { qrCodeExtractor.extract(any(), any()) } returns mockk<TestCertificateQRCode>().apply {
             every { qrCode } returns "qrCode"
             every { testCertificateData } returns mockk()
@@ -106,38 +70,9 @@ class TestCertificateRepositoryTest : BaseTest() {
     private fun createInstance(scope: CoroutineScope) = TestCertificateRepository(
         appScope = scope,
         dispatcherProvider = TestDispatcherProvider(),
-        timeStamper = timeStamper,
         storage = storage,
-        certificateServer = certificateServer,
-        rsaKeyPairGenerator = RSAKeyPairGenerator(),
-        rsaCryptography = rsaCryptography,
         qrCodeExtractor = qrCodeExtractor,
-        appConfigProvider = appConfigProvider,
         valueSetsRepository = valueSetsRepository,
+        processor = testCertificateProcessor,
     )
-
-    @Test
-    fun `refresh tries public key registration`() = runBlockingTest2(ignoreActive = true) {
-        storage.testCertificates = setOf(testCertificateNew)
-
-        val instance = createInstance(scope = this)
-        instance.refresh()
-
-        coVerify {
-            certificateServer.registerPublicKeyForTest(testCertificateNew.registrationToken, any())
-        }
-    }
-
-    @Test
-    fun `refresh skips public key registration already registered`() = runBlockingTest2(ignoreActive = true) {
-        storage.testCertificates = setOf(testCertificateWithPubKey)
-
-        val instance = createInstance(scope = this)
-        instance.refresh()
-
-        coVerify {
-            covidTestCertificateConfig.waitAfterPublicKeyRegistration
-            certificateServer.requestCertificateForTest(testCertificateNew.registrationToken)
-        }
-    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestData.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateTestData.kt
similarity index 74%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestData.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateTestData.kt
index 102501c7dd95945ab5cdfccd1f25f535bbe2da2f..0de056a4501d158461578c680059255c9397d278 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestData.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/TestCertificateTestData.kt
@@ -1,70 +1,30 @@
 package de.rki.coronawarnapp.coronatest
 
-import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateContainer
-import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateContainer
-import de.rki.coronawarnapp.covidcertificate.test.TestCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.TestCertificateDccV1
+import de.rki.coronawarnapp.coronatest.type.common.TestCertificateContainer
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACertificateData
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
-import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
-import de.rki.coronawarnapp.vaccination.core.certificate.HealthCertificateHeader
 import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Instant
 import javax.inject.Inject
 
 @Suppress("MaxLineLength")
-class CoronaTestTestData @Inject constructor(
-    private val qrCodeExtractor: TestCertificateQRCodeExtractor,
-    private val rsaKeyPairGenerator: RSAKeyPairGenerator,
+class TestCertificateTestData @Inject constructor(
+    qrCodeExtractor: TestCertificateQRCodeExtractor
 ) {
 
-    val personATest1CertQRCodeString = "personATest1CertQRCodeString"
+    val personATest1CertQRCodeString =
+        "HC1:6BFQ$9FY7$\$Q00019C-5HQ57WDQTLUMS256TUMP49JLZCX/N4VB14NRINX6J7+KF\$UB.N83CMMPVNPAHJ035FT88%AJ1R*UOGR3ZWLC24+F7DO276HB.O*BEVJODVSKNOP0T4\$FZ.R/03N6QK3A05EQVBONNHSJ9WJT+B15H NBEZ3VI8-V77AFL4NY9V*JM *KOPC2H8PR5OG9:VIG$969FJRV28N9PORZJQ43EOIHIJ+83XDDRB201N.L58EB7 8GS8. 9GPNGHFV/6\$I3R3R4930TC/ZGZESM929.D59GO13E\$H7LMUGS18ABF6YD955C C6VPNMZU+3FJR1RVLBZDR2F*8A4MKWIH+/JPU1*H6E2CTHGYHPPU6U*FYFJ6RJO*I8P1T59S:V3V1SA86L8Y8A5XB*10112G8GHK77CBOK9QEI960TTNC.I3A4P8BM6DO:MI/98PC/ZP2:JW3JB.J:R2.5GX0J$1J.OOCYSS8A*DS\$AFVJR9RT-L6N%PS%CV%B8KL0%EL SXLBSA6 %M6JEN+E0Q8A:RAGW16KGUA627-Y2:EDH\$VFVT:29FWUTJSANSYCV4PSKNP\$ZV-8T27SV4CC3CJIV20TKBS22O$/MT/V*0Q0IUE0DBPT+UP03IR1CRFOP3"
 
-    val personATest1CertHeader = HealthCertificateHeader(
-        issuer = "DE",
-        issuedAt = Instant.parse("2021-05-10T09:25:00.000Z"),
-        expiresAt = Instant.parse("2022-05-19T09:25:00.000Z"),
-    )
-
-    val personATest1Cert = TestCertificateDccV1(
-        version = "1.0.0",
-        nameData = TestCertificateDccV1.NameData(
-            givenName = "Andreas",
-            givenNameStandardized = "ANDREAS",
-            familyName = "Astrá Eins",
-            familyNameStandardized = "ASTRA<EINS",
-        ),
-        dob = "1966-11-11",
-        testCertificateData = listOf(
-            TestCertificateDccV1.TestCertificateData(
-                targetId = "840539006",
-                countryOfTest = "DE",
-                sc = Instant.EPOCH.toDateTime().toString(),
-                dr = Instant.EPOCH.toDateTime().toString(),
-                testCenter = "TODO",
-                testName = "TODO",
-                testNameAndManufactor = "TODO",
-                testResult = "TODO",
-                testType = "TODO",
-                certificateIssuer = "Bundesministerium für Gesundheit - Test01",
-                uniqueCertificateIdentifier = "01DE/00001/1119305005/7T1UG87G61Y7NRXIBQJDTYQ9#S",
-            )
-        )
-    )
-
-    val personATest1CertData = TestCertificateData(
-        header = personATest1CertHeader,
-        certificate = personATest1Cert,
-    )
-
-    val personATest1CertContainer = run {
+    val personATest1StoredData = run {
         val publicKey = RSAKey.Public(
             "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2+WCCvy0SNqZMy/V1FYYMkBTGp/5BQt/NxUW1nIkj84u6duqNNQh4GjugoDc8epyl/yi3D61Jt7qArwk+eTcnW4/jEOexT5pCabRKrFm6IMndSefYrP3CeaD86ZU47uhnRuCG3TcPhIqUN2E37EbOsI9Z59JXc5tmmB71CxTF0bjE0PNLgbTU2snnsO6+oz/JLo7D2nw6E9yxSJ8JBjM5j+FC4sYLuO2nYi/BzAGZL/wsKrajg2hjA3f8r1cgst8HdzAJjMUG90pb3UG2K2KVRScbvF8pvRrzLCvJ/gqAGDXX/M00jr407vU8V4O2A9YdSavaC02iRFTNail65cbOW96p3ptjeejofj8l5PO5eBYWERla8NrlD9EcW93+aSmswn4w9iSSq+j38GMyhYulLcOlhKTeWumc5goDjcHyri48Ki70ddGzrxFxggaC/FqlCG85A6/43fVaWH/Wi2uPDPzaRGNQzXRy4LCuE/dvUzp8TlkpcT0QFy/Q4Ke0u1dAgMBAAE\u003d".decodeBase64()!!
         )
         val privateKey = RSAKey.Private(
             "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".decodeBase64()!!
         )
-        PCRCertificateContainer(
+        PCRCertificateData(
             identifier = "identifier",
             registrationToken = "registrationToken",
             registeredAt = Instant.ofEpochMilli(12345),
@@ -74,58 +34,25 @@ class CoronaTestTestData @Inject constructor(
             certificateReceivedAt = Instant.ofEpochMilli(123456789),
             encryptedDataEncryptionkey = "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk=".decodeBase64()!!,
             testCertificateQrCode = personATest1CertQRCodeString,
-        ).apply {
-            preParsedData = personATest1CertData
-        }
+        )
     }
 
-    val personATest2CertQRCodeString = "personATest2CertQRCodeString"
-
-    val personATest2CertHeader = HealthCertificateHeader(
-        issuer = "DE",
-        issuedAt = Instant.parse("2021-05-11T09:25:00.000Z"),
-        expiresAt = Instant.parse("2022-05-11T09:25:00.000Z"),
-    )
-
-    val personATest2Cert = TestCertificateDccV1(
-        version = "1.0.0",
-        nameData = TestCertificateDccV1.NameData(
-            givenName = "Andreas",
-            givenNameStandardized = "ANDREAS",
-            familyName = "Astrá Eins",
-            familyNameStandardized = "ASTRA<EINS",
-        ),
-        dob = "1966-11-11",
-        testCertificateData = listOf(
-            TestCertificateDccV1.TestCertificateData(
-                targetId = "840539006",
-                countryOfTest = "DE",
-                sc = Instant.EPOCH.toDateTime().toString(),
-                dr = Instant.EPOCH.toDateTime().toString(),
-                testCenter = "TODO",
-                testName = "TODO",
-                testNameAndManufactor = "TODO",
-                testResult = "TODO",
-                testType = "TODO",
-                certificateIssuer = "Bundesministerium für Gesundheit - Test01",
-                uniqueCertificateIdentifier = "01DE/00001/1119305005/TODO",
-            )
-        )
+    val personATest1Container = TestCertificateContainer(
+        data = personATest1StoredData,
+        qrCodeExtractor = qrCodeExtractor,
     )
 
-    val personATest2CertData = TestCertificateData(
-        header = personATest2CertHeader,
-        certificate = personATest2Cert,
-    )
+    val personATest2CertQRCodeString =
+        "HC1:6BFT$9W08+J2DO3L6COM9W\$B8MG9DIV*GZHTGBS46FQ5G+/N1D9K1LV-50OIETJPEU63TT MA5B-+B%95V72UUSRST4662Z8NME.249C1Y*5TIT+TI0QG*%9%VBYBOIZV7UNM%2A8P1N3+IDXN38BO%619B4D515FT*5CR4F:U8M/P-7T%TGX2CDDTB/5GR8:0I$ G*+N0-CIF51925USMI2WX4XKJA0G2XHP268P7ODSZYC4TKJOO:WQ437D:E78V-5UM4LGFBKZ80YIU 8%/GWAIM%KG/VIM2 M4BKP7NI/204CE9BSYP2JGI9GJGQUJ-UEYM7YAQR6E DHZ3-RM3:BQ3KRDMIV5.WVBJ8HT8DG7T GMJ47O2HSA+P6UFGUNIPCNOPFJIPWP8E 8BB0C08F 75N6UW20BA800 8LWN3D NV:U6XRDWF9FOQ1LT+L07BFUBZU37D8ZBP+FBKWO:X1ZK8.0V9-AX02UD5PP8K81+VO*.L4*DJRR7WPEL4G-LYCL+ 9\$TBHFNU0R%GD0/ESSOQH7PZD2 BJA3R74E4WG3W02B67EF8WZN7L0J2*3R5EG0VB7OM2I92W/UMJ7G1 FNSCF O 4W4VSO2DOJUF6I8%10-65UR/JJI3AN2EW-BLRVHQN77J"
 
-    val personATest2CertContainer = run {
+    val personATest2CertStoredData = run {
         val publicKey = RSAKey.Public(
             "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnrJ8PbmbOmEEmHB/8yg1bnkUT7jcF4Xfy2Me5imJgLVYQ0cL9UNP91cfFUrgMFV3fHOc0Uuay10TmrBLaEdzqDEZQH4Kj0uZ+hVCtzntVKFviuUoh08wxFlogtc5Sy0NhuTGyC1W/i2AX1SDvet2xMcc1fE44rITQEEAlG8+nfGpbppFHezUOxuZjs9XBTxavDjQyWeFwMD30UAJGakPhOOOj6ihXA19OvQ/tYuYTJ5C9QzeK90C/rYbg2fn+os3EGlb7iJZ2V3KGrNLdMcEtkiG5IiHicaNCn8OS/cI3d29iJE4ECaF711fyF8MG1H2tbkjULS3bsPNUvyvHfM2cjOPRhejayOh+CxQkc3wKar8ApvQCjiVRW05nO0ufHdPMcWJhUlchWYO5mOJTSO8vG/9YqpnTuDc2Gelc4gMK7KATdH3v1FsACPKNJdpt68IfZXgGYn5LtJ7zJB6Yw8Rewj1SaF/wFKXpYd+5JyK18wJTLVYSpiDzidh4DP+R6ZTAgMBAAE\u003d".decodeBase64()!!
         )
         val privateKey = RSAKey.Private(
             "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".decodeBase64()!!
         )
-        RACertificateContainer(
+        RACertificateData(
             identifier = "identifier2",
             registrationToken = "registrationToken2",
             registeredAt = Instant.ofEpochMilli(12345),
@@ -135,27 +62,33 @@ class CoronaTestTestData @Inject constructor(
             certificateReceivedAt = Instant.ofEpochMilli(123456789),
             encryptedDataEncryptionkey = "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk=".decodeBase64()!!,
             testCertificateQrCode = personATest2CertQRCodeString
-        ).apply {
-            preParsedData = personATest2CertData
-        }
+        )
     }
 
-    val personATest3CertContainerNokey = run {
-        RACertificateContainer(
+    val personATest2CertContainer = TestCertificateContainer(
+        data = personATest2CertStoredData,
+        qrCodeExtractor = qrCodeExtractor,
+    )
+
+    val personATest3CertNokeyStoredData = run {
+        RACertificateData(
             identifier = "identifier2",
             registrationToken = "registrationToken2",
             registeredAt = Instant.ofEpochMilli(12345),
         )
     }
-
-    val personATest4CertContainerPending = run {
+    val personATest3CertNokeyContainer = TestCertificateContainer(
+        data = personATest3CertNokeyStoredData,
+        qrCodeExtractor = qrCodeExtractor,
+    )
+    val personATest4CertPendingStoredData = run {
         val publicKey = RSAKey.Public(
             "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnrJ8PbmbOmEEmHB/8yg1bnkUT7jcF4Xfy2Me5imJgLVYQ0cL9UNP91cfFUrgMFV3fHOc0Uuay10TmrBLaEdzqDEZQH4Kj0uZ+hVCtzntVKFviuUoh08wxFlogtc5Sy0NhuTGyC1W/i2AX1SDvet2xMcc1fE44rITQEEAlG8+nfGpbppFHezUOxuZjs9XBTxavDjQyWeFwMD30UAJGakPhOOOj6ihXA19OvQ/tYuYTJ5C9QzeK90C/rYbg2fn+os3EGlb7iJZ2V3KGrNLdMcEtkiG5IiHicaNCn8OS/cI3d29iJE4ECaF711fyF8MG1H2tbkjULS3bsPNUvyvHfM2cjOPRhejayOh+CxQkc3wKar8ApvQCjiVRW05nO0ufHdPMcWJhUlchWYO5mOJTSO8vG/9YqpnTuDc2Gelc4gMK7KATdH3v1FsACPKNJdpt68IfZXgGYn5LtJ7zJB6Yw8Rewj1SaF/wFKXpYd+5JyK18wJTLVYSpiDzidh4DP+R6ZTAgMBAAE\u003d".decodeBase64()!!
         )
         val privateKey = RSAKey.Private(
             "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".decodeBase64()!!
         )
-        RACertificateContainer(
+        RACertificateData(
             identifier = "identifier2",
             registrationToken = "registrationToken2",
             registeredAt = Instant.ofEpochMilli(12345),
@@ -164,4 +97,9 @@ class CoronaTestTestData @Inject constructor(
             rsaPrivateKey = privateKey,
         )
     }
+
+    val personATest4CertPendingContainer = TestCertificateContainer(
+        data = personATest4CertPendingStoredData,
+        qrCodeExtractor = qrCodeExtractor,
+    )
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorageTest.kt
index f26fd0bca0a021a62b96b7ad3e7a6f4681941865..7f29705d8e8f648e4e48cf8b9d715b9b1383f78d 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorageTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/storage/TestCertificateStorageTest.kt
@@ -2,18 +2,18 @@ package de.rki.coronawarnapp.coronatest.storage
 
 import android.content.Context
 import androidx.core.content.edit
-import de.rki.coronawarnapp.coronatest.CoronaTestTestData
 import de.rki.coronawarnapp.coronatest.DaggerCoronaTestTestComponent
+import de.rki.coronawarnapp.coronatest.TestCertificateTestData
 import de.rki.coronawarnapp.util.serialization.SerializationModule
 import de.rki.coronawarnapp.vaccination.core.repository.storage.ContainerPostProcessor
 import io.kotest.matchers.shouldBe
-import io.kotest.matchers.shouldNotBe
 import io.mockk.MockKAnnotations
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
+import testhelpers.extensions.toComparableJsonPretty
 import testhelpers.preferences.MockSharedPreferences
 import javax.inject.Inject
 
@@ -21,7 +21,7 @@ import javax.inject.Inject
 class TestCertificateStorageTest : BaseTest() {
     @MockK lateinit var context: Context
     private lateinit var mockPreferences: MockSharedPreferences
-    @Inject lateinit var testData: CoronaTestTestData
+    @Inject lateinit var certificateTestData: TestCertificateTestData
     @Inject lateinit var postProcessor: ContainerPostProcessor
 
     @BeforeEach
@@ -63,52 +63,45 @@ class TestCertificateStorageTest : BaseTest() {
     @Test
     fun `store two containers, one for each type`() {
         createInstance().testCertificates = setOf(
-            testData.personATest1CertContainer,
-            testData.personATest2CertContainer
+            certificateTestData.personATest1StoredData,
+            certificateTestData.personATest2CertStoredData
         )
 
-//        (mockPreferences.dataMapPeek["testcertificate.data.pcr"] as String).toComparableJsonPretty() shouldBe """
-//            [
-//              {
-//                "identifier": "identifier",
-//                "registrationToken": "registrationToken",
-//                "registeredAt": 12345,
-//                "publicKeyRegisteredAt": 6789,
-//                "rsaPublicKey": "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2+WCCvy0SNqZMy/V1FYYMkBTGp/5BQt/NxUW1nIkj84u6duqNNQh4GjugoDc8epyl/yi3D61Jt7qArwk+eTcnW4/jEOexT5pCabRKrFm6IMndSefYrP3CeaD86ZU47uhnRuCG3TcPhIqUN2E37EbOsI9Z59JXc5tmmB71CxTF0bjE0PNLgbTU2snnsO6+oz/JLo7D2nw6E9yxSJ8JBjM5j+FC4sYLuO2nYi/BzAGZL/wsKrajg2hjA3f8r1cgst8HdzAJjMUG90pb3UG2K2KVRScbvF8pvRrzLCvJ/gqAGDXX/M00jr407vU8V4O2A9YdSavaC02iRFTNail65cbOW96p3ptjeejofj8l5PO5eBYWERla8NrlD9EcW93+aSmswn4w9iSSq+j38GMyhYulLcOlhKTeWumc5goDjcHyri48Ki70ddGzrxFxggaC/FqlCG85A6/43fVaWH/Wi2uPDPzaRGNQzXRy4LCuE/dvUzp8TlkpcT0QFy/Q4Ke0u1dAgMBAAE\u003d",
-//                "rsaPrivateKey": "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",
-//                "certificateReceivedAt": 123456789,
-//                "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d",
-//                "testCertificateQrCode": "personATest1CertQRCodeString"
-//              }
-//            ]
-//        """.toComparableJsonPretty()
-//
-//        (mockPreferences.dataMapPeek["testcertificate.data.ra"] as String).toComparableJsonPretty() shouldBe """
-//            [
-//              {
-//                "identifier": "identifier2",
-//                "registrationToken": "registrationToken2",
-//                "registeredAt": 12345,
-//                "publicKeyRegisteredAt": 6789,
-//                "rsaPublicKey": "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnrJ8PbmbOmEEmHB/8yg1bnkUT7jcF4Xfy2Me5imJgLVYQ0cL9UNP91cfFUrgMFV3fHOc0Uuay10TmrBLaEdzqDEZQH4Kj0uZ+hVCtzntVKFviuUoh08wxFlogtc5Sy0NhuTGyC1W/i2AX1SDvet2xMcc1fE44rITQEEAlG8+nfGpbppFHezUOxuZjs9XBTxavDjQyWeFwMD30UAJGakPhOOOj6ihXA19OvQ/tYuYTJ5C9QzeK90C/rYbg2fn+os3EGlb7iJZ2V3KGrNLdMcEtkiG5IiHicaNCn8OS/cI3d29iJE4ECaF711fyF8MG1H2tbkjULS3bsPNUvyvHfM2cjOPRhejayOh+CxQkc3wKar8ApvQCjiVRW05nO0ufHdPMcWJhUlchWYO5mOJTSO8vG/9YqpnTuDc2Gelc4gMK7KATdH3v1FsACPKNJdpt68IfZXgGYn5LtJ7zJB6Yw8Rewj1SaF/wFKXpYd+5JyK18wJTLVYSpiDzidh4DP+R6ZTAgMBAAE\u003d",
-//                "rsaPrivateKey": "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",
-//                "certificateReceivedAt": 123456789,
-//                "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d",
-//                "testCertificateQrCode": "personATest2CertQRCodeString"
-//              }
-//            ]
-//        """.toComparableJsonPretty()
+        (mockPreferences.dataMapPeek["testcertificate.data.pcr"] as String).toComparableJsonPretty() shouldBe """
+            [
+              {
+                "identifier": "identifier",
+                "registrationToken": "registrationToken",
+                "registeredAt": 12345,
+                "publicKeyRegisteredAt": 6789,
+                "rsaPublicKey": "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2+WCCvy0SNqZMy/V1FYYMkBTGp/5BQt/NxUW1nIkj84u6duqNNQh4GjugoDc8epyl/yi3D61Jt7qArwk+eTcnW4/jEOexT5pCabRKrFm6IMndSefYrP3CeaD86ZU47uhnRuCG3TcPhIqUN2E37EbOsI9Z59JXc5tmmB71CxTF0bjE0PNLgbTU2snnsO6+oz/JLo7D2nw6E9yxSJ8JBjM5j+FC4sYLuO2nYi/BzAGZL/wsKrajg2hjA3f8r1cgst8HdzAJjMUG90pb3UG2K2KVRScbvF8pvRrzLCvJ/gqAGDXX/M00jr407vU8V4O2A9YdSavaC02iRFTNail65cbOW96p3ptjeejofj8l5PO5eBYWERla8NrlD9EcW93+aSmswn4w9iSSq+j38GMyhYulLcOlhKTeWumc5goDjcHyri48Ki70ddGzrxFxggaC/FqlCG85A6/43fVaWH/Wi2uPDPzaRGNQzXRy4LCuE/dvUzp8TlkpcT0QFy/Q4Ke0u1dAgMBAAE\u003d",
+                "rsaPrivateKey": "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",
+                "certificateReceivedAt": 123456789,
+                "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d",
+                "testCertificateQrCode": "${certificateTestData.personATest1CertQRCodeString}"
+              }
+            ]
+        """.toComparableJsonPretty()
+
+        (mockPreferences.dataMapPeek["testcertificate.data.ra"] as String).toComparableJsonPretty() shouldBe """
+            [
+              {
+                "identifier": "identifier2",
+                "registrationToken": "registrationToken2",
+                "registeredAt": 12345,
+                "publicKeyRegisteredAt": 6789,
+                "rsaPublicKey": "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnrJ8PbmbOmEEmHB/8yg1bnkUT7jcF4Xfy2Me5imJgLVYQ0cL9UNP91cfFUrgMFV3fHOc0Uuay10TmrBLaEdzqDEZQH4Kj0uZ+hVCtzntVKFviuUoh08wxFlogtc5Sy0NhuTGyC1W/i2AX1SDvet2xMcc1fE44rITQEEAlG8+nfGpbppFHezUOxuZjs9XBTxavDjQyWeFwMD30UAJGakPhOOOj6ihXA19OvQ/tYuYTJ5C9QzeK90C/rYbg2fn+os3EGlb7iJZ2V3KGrNLdMcEtkiG5IiHicaNCn8OS/cI3d29iJE4ECaF711fyF8MG1H2tbkjULS3bsPNUvyvHfM2cjOPRhejayOh+CxQkc3wKar8ApvQCjiVRW05nO0ufHdPMcWJhUlchWYO5mOJTSO8vG/9YqpnTuDc2Gelc4gMK7KATdH3v1FsACPKNJdpt68IfZXgGYn5LtJ7zJB6Yw8Rewj1SaF/wFKXpYd+5JyK18wJTLVYSpiDzidh4DP+R6ZTAgMBAAE\u003d",
+                "rsaPrivateKey": "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",
+                "certificateReceivedAt": 123456789,
+                "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d",
+                "testCertificateQrCode": "${certificateTestData.personATest2CertQRCodeString}"
+              }
+            ]
+        """.toComparableJsonPretty()
 
         createInstance().testCertificates shouldBe setOf(
-            testData.personATest1CertContainer,
-            testData.personATest2CertContainer
+            certificateTestData.personATest1StoredData,
+            certificateTestData.personATest2CertStoredData
         )
     }
-
-    @Test
-    fun `post processor injects data extractors`() {
-        createInstance().testCertificates = setOf(testData.personATest1CertContainer)
-
-        createInstance().testCertificates.single().qrCodeExtractor shouldNotBe null
-    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
index 6459f54ed4d8b69fff4ce8a45ab90e996d913ee8..b50001b929e9254d01120308f3d4b691ce1d829a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
@@ -1,7 +1,7 @@
 package de.rki.coronawarnapp.coronatest.type
 
-import de.rki.coronawarnapp.coronatest.CoronaTestTestData
 import de.rki.coronawarnapp.coronatest.DaggerCoronaTestTestComponent
+import de.rki.coronawarnapp.coronatest.TestCertificateTestData
 import io.kotest.matchers.shouldBe
 import io.kotest.matchers.shouldNotBe
 import io.mockk.mockk
@@ -13,7 +13,7 @@ import javax.inject.Inject
 
 class TestCertificateContainerTest : BaseTest() {
 
-    @Inject lateinit var testData: CoronaTestTestData
+    @Inject lateinit var certificateTestData: TestCertificateTestData
 
     @BeforeEach
     fun setup() {
@@ -22,33 +22,33 @@ class TestCertificateContainerTest : BaseTest() {
 
     @Test
     fun `ui facing test certificate creation and fallbacks`() {
-        testData.personATest2CertContainer.apply {
+        certificateTestData.personATest2CertContainer.apply {
             isPublicKeyRegistered shouldBe true
             isCertificateRetrievalPending shouldBe false
-            certificateId shouldBe "01DE/00001/1119305005/TODO"
-            testCertificateQrCode shouldBe "personATest2CertQRCodeString"
-            certificateReceivedAt shouldBe Instant.parse("1970-01-02T10:17:36.789Z")
+            certificateId shouldBe "URN:UVCI:V1:DE:7WR8CE12Y8O2AN4NK320TPNKB1"
+            data.testCertificateQrCode shouldBe certificateTestData.personATest2CertQRCodeString
+            data.certificateReceivedAt shouldBe Instant.parse("1970-01-02T10:17:36.789Z")
             toTestCertificate(null) shouldNotBe null
         }
     }
 
     @Test
     fun `pending check and nullability`() {
-        testData.personATest3CertContainerNokey.apply {
+        certificateTestData.personATest3CertNokeyContainer.apply {
             isPublicKeyRegistered shouldBe false
             isCertificateRetrievalPending shouldBe true
             certificateId shouldBe null
-            testCertificateQrCode shouldBe null
-            certificateReceivedAt shouldBe null
+            data.testCertificateQrCode shouldBe null
+            data.certificateReceivedAt shouldBe null
             toTestCertificate(mockk()) shouldBe null
         }
 
-        testData.personATest4CertContainerPending.apply {
+        certificateTestData.personATest4CertPendingContainer.apply {
             isPublicKeyRegistered shouldBe true
             isCertificateRetrievalPending shouldBe true
             certificateId shouldBe null
-            testCertificateQrCode shouldBe null
-            certificateReceivedAt shouldBe null
+            data.testCertificateQrCode shouldBe null
+            data.certificateReceivedAt shouldBe null
             toTestCertificate(mockk()) shouldBe null
         }
     }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b409eb693632a06370a709c6c8ed95439b1ca6cc
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/common/TestCertificateProcessorTest.kt
@@ -0,0 +1,118 @@
+package de.rki.coronawarnapp.coronatest.type.common
+
+import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.appconfig.ConfigData
+import de.rki.coronawarnapp.appconfig.CovidCertificateConfig
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.server.CovidCertificateServer
+import de.rki.coronawarnapp.covidcertificate.server.TestCertificateComponents
+import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCode
+import de.rki.coronawarnapp.covidcertificate.test.TestCertificateQRCodeExtractor
+import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
+import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
+import io.mockk.MockKAnnotations
+import io.mockk.Runs
+import io.mockk.coEvery
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.mockk
+import kotlinx.coroutines.flow.flowOf
+import okio.ByteString
+import org.joda.time.Duration
+import org.joda.time.Instant
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import testhelpers.coroutines.runBlockingTest2
+
+class TestCertificateProcessorTest : BaseTest() {
+
+    @MockK lateinit var timeStamper: TimeStamper
+    @MockK lateinit var certificateServer: CovidCertificateServer
+    @MockK lateinit var rsaCryptography: RSACryptography
+    @MockK lateinit var qrCodeExtractor: TestCertificateQRCodeExtractor
+    @MockK lateinit var appConfigProvider: AppConfigProvider
+    @MockK lateinit var appConfigData: ConfigData
+    @MockK lateinit var covidTestCertificateConfig: CovidCertificateConfig.TestCertificate
+
+    private val testCertificateNew = PCRCertificateData(
+        identifier = "identifier1",
+        registrationToken = "regtoken1",
+        registeredAt = Instant.EPOCH,
+    )
+
+    private val testCertificateWithPubKey = testCertificateNew.copy(
+        publicKeyRegisteredAt = Instant.EPOCH,
+        rsaPublicKey = mockk(),
+        rsaPrivateKey = mockk(),
+    )
+
+    private val testCerticateComponents = mockk<TestCertificateComponents>().apply {
+        every { dataEncryptionKeyBase64 } returns "dek"
+        every { encryptedCoseTestCertificateBase64 } returns ""
+    }
+
+    private var storageSet = mutableSetOf<StoredTestCertificateData>()
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+
+        every { timeStamper.nowUTC } returns Instant.EPOCH
+
+        every { appConfigProvider.currentConfig } returns flowOf(appConfigData)
+        every { appConfigData.covidCertificateParameters } returns mockk<CovidCertificateConfig>().apply {
+            every { testCertificate } returns covidTestCertificateConfig
+        }
+
+        covidTestCertificateConfig.apply {
+            every { waitForRetry } returns Duration.standardSeconds(10)
+            every { waitAfterPublicKeyRegistration } returns Duration.standardSeconds(10)
+        }
+
+        certificateServer.apply {
+            coEvery { registerPublicKeyForTest(any(), any()) } just Runs
+            coEvery { requestCertificateForTest(any()) } returns testCerticateComponents
+        }
+
+        every { rsaCryptography.decrypt(any(), any()) } returns ByteString.Companion.EMPTY
+
+        coEvery { qrCodeExtractor.extract(any(), any()) } returns mockk<TestCertificateQRCode>().apply {
+            every { qrCode } returns "qrCode"
+            every { testCertificateData } returns mockk()
+        }
+    }
+
+    private fun createInstance() = TestCertificateProcessor(
+        qrCodeExtractor = qrCodeExtractor,
+        timeStamper = timeStamper,
+        certificateServer = certificateServer,
+        rsaKeyPairGenerator = RSAKeyPairGenerator(),
+        rsaCryptography = rsaCryptography,
+        appConfigProvider = appConfigProvider,
+    )
+
+    @Test
+    fun `public key registration`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance()
+        instance.registerPublicKey(testCertificateNew)
+
+        coVerify {
+            certificateServer.registerPublicKeyForTest(testCertificateNew.registrationToken, any())
+        }
+    }
+
+    @Test
+    fun `obtain certificate components`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance()
+        instance.obtainCertificate(testCertificateWithPubKey)
+
+        coVerify {
+            covidTestCertificateConfig.waitAfterPublicKeyRegistration
+            certificateServer.requestCertificateForTest(testCertificateNew.registrationToken)
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessorTest.kt
index 5a59b24045cfedeca860fc2983bb76600da89466..04e5a7110f6f46ccf7ebac591793fc89b0892b98 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRProcessorTest.kt
@@ -100,7 +100,7 @@ class PCRProcessorTest : BaseTest() {
         runBlocking { PcrTeleTanCensor.clearTans() }
     }
 
-    fun createInstance() = PCRProcessor(
+    fun createInstance() = PCRTestProcessor(
         timeStamper = timeStamper,
         submissionService = submissionService,
         analyticsKeySubmissionCollector = analyticsKeySubmissionCollector,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenProcessorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessorTest.kt
similarity index 94%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenProcessorTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessorTest.kt
index 8d3affbb2c77dad1f6a26825caf6523663d1de28..2846d0f54b9f17b104b72c59e83d4295f94f8f4f 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenProcessorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RAProcessorTest.kt
@@ -16,6 +16,7 @@ import de.rki.coronawarnapp.coronatest.server.CoronaTestResult.values
 import de.rki.coronawarnapp.coronatest.server.CoronaTestResultResponse
 import de.rki.coronawarnapp.coronatest.server.RegistrationData
 import de.rki.coronawarnapp.coronatest.server.RegistrationRequest
+import de.rki.coronawarnapp.coronatest.server.VerificationKeyType
 import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.coronatest.type.CoronaTestService
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
@@ -26,6 +27,7 @@ import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.coEvery
+import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import io.mockk.just
@@ -37,7 +39,7 @@ import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 
-class RapidAntigenProcessorTest : BaseTest() {
+class RAProcessorTest : BaseTest() {
 
     @MockK lateinit var timeStamper: TimeStamper
     @MockK lateinit var submissionService: CoronaTestService
@@ -95,7 +97,7 @@ class RapidAntigenProcessorTest : BaseTest() {
         }
     }
 
-    fun createInstance() = RAProcessor(
+    fun createInstance() = RATestProcessor(
         timeStamper = timeStamper,
         submissionService = submissionService,
         analyticsKeySubmissionCollector = analyticsKeySubmissionCollector,
@@ -141,6 +143,27 @@ class RapidAntigenProcessorTest : BaseTest() {
         instance.pollServer(past60DaysTest).testResult shouldBe RAT_REDEEMED
     }
 
+    @Test
+    fun `registering a new test`() = runBlockingTest {
+        val request = CoronaTestQRCode.RapidAntigen(
+            hash = "hash",
+            createdAt = Instant.EPOCH,
+        )
+
+        val instance = createInstance()
+        instance.create(request)
+
+        val expectedServerRequest = RegistrationRequest(
+            key = request.registrationIdentifier,
+            type = VerificationKeyType.GUID,
+            dateOfBirthKey = null,
+        )
+
+        coVerify {
+            submissionService.registerTest(expectedServerRequest)
+        }
+    }
+
     @Test
     fun `registering a new test maps invalid results to INVALID state`() = runBlockingTest {
         var registrationData = RegistrationData(