Commit 5049f6c5 authored by stopcovid@lunabee.com's avatar stopcovid@lunabee.com
Browse files

Update to 3.3.4

- Show time for DCC
- Change recovery start date
- Hide keyFigure without label
- Pin intermediate certificate instead of leaf one
parent 50a9b7ed
......@@ -166,7 +166,6 @@ object AnalyticsManager : LifecycleObserver {
val result = AnalyticsServerManager.sendAnalytics(
context,
analyticsInfosProvider.getBaseUrl(),
analyticsInfosProvider.getCertificateSha256(),
analyticsInfosProvider.getApiVersion(),
token,
sendAnalyticsRQ
......@@ -205,7 +204,6 @@ object AnalyticsManager : LifecycleObserver {
val result = AnalyticsServerManager.sendAnalytics(
context,
analyticsInfosProvider.getBaseUrl(),
analyticsInfosProvider.getCertificateSha256(),
analyticsInfosProvider.getApiVersion(),
token,
sendAnalyticsRQ,
......@@ -236,7 +234,6 @@ object AnalyticsManager : LifecycleObserver {
val result = AnalyticsServerManager.deleteAnalytics(
context,
analyticsInfosProvider.getBaseUrl(),
analyticsInfosProvider.getCertificateSha256(),
analyticsInfosProvider.getApiVersion(),
token,
installationUUID,
......
......@@ -19,9 +19,7 @@ import com.lunabeestudio.analytics.model.AnalyticsServiceName
import com.lunabeestudio.analytics.network.model.SendAnalyticsRQ
import com.lunabeestudio.analytics.network.model.SendAppAnalyticsRQ
import com.lunabeestudio.analytics.network.model.SendHealthAnalyticsRQ
import okhttp3.CertificatePinner
import okhttp3.ConnectionSpec
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.TlsVersion
......@@ -37,7 +35,7 @@ import java.util.concurrent.TimeUnit
internal object AnalyticsServerManager {
private fun getRetrofit(context: Context, baseUrl: String, certificateSha256: String, token: String): AnalyticsApi {
private fun getRetrofit(context: Context, baseUrl: String, token: String): AnalyticsApi {
return Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(MoshiConverterFactory.create())
......@@ -50,16 +48,8 @@ internal object AnalyticsServerManager {
connectionSpecs(listOf(requireTls12))
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
certificatePinner(
CertificatePinner.Builder()
.add(
baseUrl.toHttpUrl().host,
certificateSha256
)
.build()
)
val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
.addTrustedCertificate(certificateFromString(context, "analytics_api_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "certigna_services"))
.build()
sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
}
......@@ -79,18 +69,17 @@ internal object AnalyticsServerManager {
suspend fun sendAnalytics(
context: Context,
baseUrl: String,
certificateSha256: String,
apiVersion: String,
token: String,
sendAnalyticsRQ: SendAnalyticsRQ
): AnalyticsResult {
return try {
val result = when (sendAnalyticsRQ) {
is SendAppAnalyticsRQ -> getRetrofit(context, baseUrl, certificateSha256, token).sendAppAnalytics(
is SendAppAnalyticsRQ -> getRetrofit(context, baseUrl, token).sendAppAnalytics(
apiVersion,
sendAnalyticsRQ
)
is SendHealthAnalyticsRQ -> getRetrofit(context, baseUrl, certificateSha256, token).sendHealthAnalytics(
is SendHealthAnalyticsRQ -> getRetrofit(context, baseUrl, token).sendHealthAnalytics(
apiVersion,
sendAnalyticsRQ
)
......@@ -109,13 +98,12 @@ internal object AnalyticsServerManager {
suspend fun deleteAnalytics(
context: Context,
baseUrl: String,
certificateSha256: String,
apiVersion: String,
token: String,
installationUuid: String,
): AnalyticsResult {
return try {
val result = getRetrofit(context, baseUrl, certificateSha256, token).deleteAnalytics(apiVersion, installationUuid)
val result = getRetrofit(context, baseUrl, token).deleteAnalytics(apiVersion, installationUuid)
if (result.isSuccessful) {
AnalyticsResult.Success()
} else {
......
......@@ -12,7 +12,6 @@ package com.lunabeestudio.analytics.proxy
interface AnalyticsInfosProvider {
fun getBaseUrl(): String
fun getCertificateSha256(): String
fun getApiVersion(): String
fun getAppVersion(): String
fun getAppBuild(): Int
......
-----BEGIN CERTIFICATE-----
MIIIJzCCBg+gAwIBAgIQAbJ0YWTU2p0z1wc5lu+m2zANBgkqhkiG9w0BAQsFADB9
MQswCQYDVQQGEwJGUjESMBAGA1UECgwJREhJTVlPVElTMRwwGgYDVQQLDBMwMDAy
IDQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQRhDBROVFJGUi00ODE0NjMwODEwMDAzNjEd
MBsGA1UEAwwUQ2VydGlnbmEgU2VydmljZXMgQ0EwHhcNMjEwMzA5MjMwMDAwWhcN
MjIwMzA5MjI1OTU5WjCBwDELMAkGA1UEBhMCRlIxDjAMBgNVBAcMBVBBUklTMUEw
PwYDVQQKDDhTRUNSRVRBUklBVCBHRU5FUkFMIE1JTklTVEVSRVMgQ0hBUkdFUyBB
RkZBSVJFUyBTT0NJQUxFUzEcMBoGA1UECwwTMDAwMiAxMzAwMDY4MDIwMDAxNjEs
MCoGA1UEAwwjYW5hbHl0aWNzLWFwaS50b3VzYW50aWNvdmlkLmdvdXYuZnIxEjAQ
BgNVBAUTCVMxOTMwNjAwODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJhsNrVXDqBCPyp8MDG+94OY0m3itFPDkII1CQmG2sFI8CAjPv/O9ggRJLtOtaYW
kn/rpBhSN/Sw51UlDi1I8k56Oovfel8b38qBmLleDa1cKBD1B+l/5mhM6T0azysT
uxIC6zW4qkK9kX1p+oS5a7aB48lWJBpisKWyNz/XzuaYaio0DSACBfqJYKZJ5PCK
tYGdhSLmBuJY/huTG1Ok2QSd+vlslKXbX8ML6PuZ1+ksNY3dwhogX1g/le5WvGhc
VNPhx8Q5yDiyf00tHFae3Af9cV91QKJjTfnj6/DPL8/tW5IJo3XHHseLkIJd3GOp
wurV7sguKCdkREWtvXl2/HkCAwEAAaOCA10wggNZMIHkBggrBgEFBQcBAQSB1zCB
1DA4BggrBgEFBQcwAoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20vc2Vy
dmljZXNjYS5kZXIwNgYIKwYBBQUHMAKGKmh0dHA6Ly9hdXRvcml0ZS5jZXJ0aWdu
YS5mci9zZXJ2aWNlc2NhLmRlcjAwBggrBgEFBQcwAYYkaHR0cDovL3NlcnZpY2Vz
Y2Eub2NzcC5kaGlteW90aXMuY29tMC4GCCsGAQUFBzABhiJodHRwOi8vc2Vydmlj
ZXNjYS5vY3NwLmNlcnRpZ25hLmZyMB8GA1UdIwQYMBaAFKzsho9LNxy4fxcbGdCu
6E7jNFwSMAkGA1UdEwQCMAAwYQYDVR0gBFowWDAIBgZngQwBAgIwTAYLKoF6AYEx
AgUBAQEwPTA7BggrBgEFBQcCARYvaHR0cHM6Ly93d3cuY2VydGlnbmEuY29tL2F1
dG9yaXRlLWNlcnRpZmljYXRpb24wZQYDVR0fBF4wXDAroCmgJ4YlaHR0cDovL2Ny
bC5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmNybDAtoCugKYYnaHR0cDovL2NybC5k
aGlteW90aXMuY29tL3NlcnZpY2VzY2EuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMB
MA4GA1UdDwEB/wQEAwIFoDAuBgNVHREEJzAlgiNhbmFseXRpY3MtYXBpLnRvdXNh
bnRpY292aWQuZ291di5mcjAdBgNVHQ4EFgQUn517X8Kv0s5zAKj4aVz1al88vhcw
ggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgBGpVXrdfqRIDC1oolp9PN9ESxBdL79
SbiFq/L8cP5tRwAAAXgbK3gxAAAEAwBHMEUCIEVKytS7HCz2X5qPEwvTtLgoo460
bpNULQSHF4OiJh9nAiEAwz/M4bCcaNJjqNxlsYiphdeJJT6sdiRNV5MHaAE7ocYA
dgBByMqx3yJGShDGoToJQodeTjGLGwPr60vHaPCQYpYG9gAAAXgbK3mGAAAEAwBH
MEUCIQCwN+4YXuep5Aw/033VDN2rtLyfCgJbiSzq5pmOB3BSqgIgXazvuM7ZtdP5
PFBYLo2tuS7Y9oONFHBFot8bv+D4SaUwDQYJKoZIhvcNAQELBQADggIBADcYwEdW
4kUOgzIs1AmUiS5vHkEZWvxwMBFsncjRPKg2t1dRWO+U7W8+uOTPb+keDf7ANs+t
VgxOrDZe0cDPgrS/dzV+YYQJpN+ZrEqYTgE6t+KUQhOjPYXN7rI5jR488MVuxJ77
TqgAls0pnL7zJ1EOPDy/TPAi6AbACGnI3bMws7p3JFXrbYP69sfOdgCSZ0GugPlQ
9qor1KWEWQe/vk6gB3lhthGy5ilQ+7I+eyxLSkVx4gvkq4gs9TB1ftzrq65+nFqq
vjjOd83I95zKcfYckeUtmLIDDGld3QkM1/x6z/X1q6bwXYFySGjTOf/OS7Nbo4ri
sVqCj/UBRPBq1VdxKmA9XK8kW6dL902IAoIxlElLdDwK/V/E6W/vSJm38iwKntrh
5rVEAw5MdewUSNMJSI6mxXURyTqEtY+DtLHeUkv4ACWx8JcRNKtYJThciCDcHwqX
j7qJPC3xx88hxwtGsIxk/DI6uEBUHJYngvtfCPP8SuuUKaIkH1U5gohf/u/Owqhf
DpTOyntXqvG7d5OEFAxiJCX4dknq2N6+C3ZhDT8txXBC3m/jUCwdhZPftnLdYE8X
hDIBME9uZ3dmMot56vublEuTxY74kXCVlNtHK2H7sT0uW1/BW7VW4FY8cUO6cKcB
lWZYJihEho4Q/pecw2DwWwZgK4ewz0Sh2fPF
-----END CERTIFICATE-----
\ No newline at end of file
......@@ -12,7 +12,7 @@ package com.lunabeestudio.stopcovid.coreui
object ConfigConstant {
private const val BASE_URL: String = "https://app.tousanticovid.gouv.fr/"
private const val VERSION_PATH: String = "json/version-33/"
private const val VERSION_PATH: String = "json/version-34/"
private const val VERSIONED_SERVER_URL: String = BASE_URL + VERSION_PATH
const val SERVER_CERTIFICATE_SHA256: String = "sha256/ckVocY6+T4RvpXWtbqOF45qEvNls4oFWi83BryOQgOk="
......
......@@ -14,32 +14,24 @@ enum class EnvConstant {
Prod {
override val captchaApiKey: String = "6LettPsUAAAAAHYaFdRBOilHUgmTMSIPKNZN4D7l"
override val baseUrl: String = "https://api.tousanticovid.gouv.fr"
override val certificateSha256: String = "sha256/xrPKKhmYeHgk4v57GcqYPrFpnI3f1FTmEfol9WIicaI="
override val cleaStatusBaseUrl: String = "https://s3.fr-par.scw.cloud/clea-batch/"
override val cleaReportBaseUrl: String = "https://signal-api.tousanticovid.gouv.fr/"
override val cleaReportCertificateSha256: String = "sha256/tnjjbtuXZUSyK1uReQhvmtspPS7IUl95cs9G8RvfVUs="
override val analyticsBaseUrl: String = "https://analytics-api.tousanticovid.gouv.fr"
override val analyticsCertificateSha256: String = "sha256/KhFx3fIev58nbXs9m2WqXDbqYrE/7r4J9cP1QqPHtVk="
override val configFilename: String = "config.json"
override val calibrationFilename: String = "calibrationBle.json"
override val serverPublicKey: String =
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAc9IDt6qJq453SwyWPB94JaLB2VfTAcL43YVtMr3HhDCd22gKaQXIbX1d+tNhfvaKM51sxeaXziPjntUzbTNiw=="
override val dccCertificatesFilename: String = "dcc-certs.json"
override val conversionCertificateSha256: String = "sha256/tlRuGxB3uGL0nVnnz6bXoGQi5aGuZ0rfqGlUlndK/yc="
};
abstract val captchaApiKey: String
abstract val baseUrl: String
abstract val certificateSha256: String
abstract val cleaStatusBaseUrl: String
abstract val cleaReportBaseUrl: String
abstract val cleaReportCertificateSha256: String
abstract val analyticsBaseUrl: String
abstract val analyticsCertificateSha256: String
abstract val configFilename: String
abstract val calibrationFilename: String
abstract val serverPublicKey: String
abstract val dccCertificatesFilename: String
abstract val conversionCertificateSha256: String
}
}
\ No newline at end of file
......@@ -44,7 +44,7 @@ object OkHttpClient {
.build()
)
val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
.addTrustedCertificate(certificateFromString(context, "app_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "certigna_services"))
.build()
sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
}
......
-----BEGIN CERTIFICATE-----
MIIIFTCCBf2gAwIBAgIRALcXz4LkL+QSSQsD8fyioHwwDQYJKoZIhvcNAQELBQAw
fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw
MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx
HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIxMDIxODIzMDAwMFoX
DTIyMDIxODIyNTk1OVowgbYxCzAJBgNVBAYTAkZSMQ4wDAYDVQQHDAVQQVJJUzFB
MD8GA1UECgw4U0VDUkVUQVJJQVQgR0VORVJBTCBNSU5JU1RFUkVTIENIQVJHRVMg
QUZGQUlSRVMgU09DSUFMRVMxHDAaBgNVBAsMEzAwMDIgMTMwMDA2ODAyMDAwMTYx
IjAgBgNVBAMMGWFwcC50b3VzYW50aWNvdmlkLmdvdXYuZnIxEjAQBgNVBAUTCVMx
OTEyOTAwOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMAXOjQkASWo
a2ynbzj5MZkCaFFJ/vV1qUH34BIbXEZxIY7uebiv2B2/LdlCy32aRY20qFJaQaBy
5VGY1VeQ9QfekPt3K/JFQCZ2eT9UYwpFY0B8VOXHIDMB811C9FmeVc7jgx9U4ZPJ
zyxRxOABR26OtmuhghooVwCNb0j4Xlxvi1eej6d55b6AN+oUBhkEV7RetI81WfEW
DalEp7hB7p6rzI6WIHDld9uE6HHtBLVi07ZBCzRJ/gv4QmCkC/vyesdxf+c/+nZd
8FhvAgPwABbVoH6vPVZinB4OdnO6FDM93eU/uIIZz148AYRYGOOPqOhqhHlPUIu/
YF8WKRR8Wn0CAwEAAaOCA1QwggNQMIHkBggrBgEFBQcBAQSB1zCB1DA4BggrBgEF
BQcwAoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5k
ZXIwNgYIKwYBBQUHMAKGKmh0dHA6Ly9hdXRvcml0ZS5jZXJ0aWduYS5mci9zZXJ2
aWNlc2NhLmRlcjAwBggrBgEFBQcwAYYkaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5k
aGlteW90aXMuY29tMC4GCCsGAQUFBzABhiJodHRwOi8vc2VydmljZXNjYS5vY3Nw
LmNlcnRpZ25hLmZyMB8GA1UdIwQYMBaAFKzsho9LNxy4fxcbGdCu6E7jNFwSMAkG
A1UdEwQCMAAwYQYDVR0gBFowWDAIBgZngQwBAgIwTAYLKoF6AYExAgUBAQEwPTA7
BggrBgEFBQcCARYvaHR0cHM6Ly93d3cuY2VydGlnbmEuY29tL2F1dG9yaXRlLWNl
cnRpZmljYXRpb24wZQYDVR0fBF4wXDAroCmgJ4YlaHR0cDovL2NybC5jZXJ0aWdu
YS5mci9zZXJ2aWNlc2NhLmNybDAtoCugKYYnaHR0cDovL2NybC5kaGlteW90aXMu
Y29tL3NlcnZpY2VzY2EuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB
/wQEAwIFoDAkBgNVHREEHTAbghlhcHAudG91c2FudGljb3ZpZC5nb3V2LmZyMB0G
A1UdDgQWBBRk93SoQeXI57Zyv3ytBcFWye+gDzCCAQUGCisGAQQB1nkCBAIEgfYE
gfMA8QB2AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABd7lezfQA
AAQDAEcwRQIhAJ/RrMKOkXjL0a/FINjyO0Nj7bxHMY4uEkMykfok+5GIAiBskbWe
aepyd479T/z1DJF4xXL7FEDA+L6ZdQSJnGNH9gB3AEHIyrHfIkZKEMahOglCh15O
MYsbA+vrS8do8JBilgb2AAABd7le1wEAAAQDAEgwRgIhAJL+Fv0hAGPuXINzUfEQ
0/3wI9khVDDYeRJGJ7BibtisAiEA6OdPh7Bqqd3FoaKH5cfJ3bvwkQhGqdP9C1RF
9Uhf+vwwDQYJKoZIhvcNAQELBQADggIBAGoFzOWnJo0BF43T3O0Ip+yvrVyWiCoO
KAGAF6uGhYbLZShMTk5XwexS8ldNCQpEAlDiZaKv0KtJM8UuBzIRei7yQoMviajb
BRl4vDMIbr9+JHPZjkhWeDzGYm11h/eINEygU1iqBPhMC/gtKrcsg9cBeWJZztmL
QQMhpw6R4UhKwKyQ3faC6c/HVsH1oZodcVa3+73a5aS6gHJoYENykebr3mC2wUAr
erZyCBkyqkIXCpqnhTE1ikWouWb0Rb0BbiUM1RNOQb5Djq5Ax4+6hkN1pFkimxO/
1uT4g+WnWkMjXtdolytZziS9p2Agkjb50mGRwsfCDNSqVXjH7/+yICnwo7TVwb/G
4Z3Mu4qRGJCA+Zek2naHs08UBexJtS1sPDzXk9Y/xsvS7Bf8bxcOELqV50aRAqEc
ynzKl8KzqeBH4kH99uNtk/9E51cMH7rexC28AU/IgPxx6/0vILITJBQb56vg3Hxj
rSeehwX1lR0pg3wVQKDM+lZ8t3dcnCeuezFqjc/jXvmQ4MvumrDpydsZPNl9iCWU
KSPZ7B7T88t9j2pIXXN1h6tA3IMmmiWDhh1B4e8j9utdo1Qohq/30xzhqKZ/JUXO
25H88b9hqADHl5moyLwrLbwYa5EOS5Epvt+IzgAz9act/7MjBAXSBd+PTc+8iivW
Ubj5RyQMYHcl
-----END CERTIFICATE-----
\ No newline at end of file
......@@ -34,7 +34,6 @@ class CleaServiceTest {
dataSource = CleaDataSource(
ApplicationProvider.getApplicationContext(),
server.url("/").toString(),
"sha256/tb6+ch/VeDZl6rHlWfL4fCAQHyCmkexJhYBa7drUmxY=",
server.url("/").toString(),
)
}
......
......@@ -39,7 +39,6 @@ class RobertServiceTest {
dataSource = ServiceDataSource(
ApplicationProvider.getApplicationContext(),
server.url("/api/v1.0/").toString(),
""
)
}
......
......@@ -49,11 +49,9 @@ class SecureKeystoreDataSource(context: Context, private val cryptoManager: Loca
override var isRegistered: Boolean
get() {
val value: Boolean? = getEncryptedValue(SHARED_PREF_KEY_IS_REGISTERED, Boolean::class.java)
return if (value == null) {
isRegistered = kA != null && kEA != null
false
} else {
value
return value ?: (kA != null && kEA != null).let {
isRegistered = it
it
}
}
set(value) = setEncryptedValue(SHARED_PREF_KEY_IS_REGISTERED, value)
......
......@@ -15,7 +15,6 @@ import android.os.Build
import com.lunabeestudio.domain.model.CacheConfig
import com.lunabeestudio.framework.BuildConfig
import okhttp3.Cache
import okhttp3.CertificatePinner
import okhttp3.ConnectionSpec
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
......@@ -35,7 +34,6 @@ object RetrofitClient {
internal fun <T> getService(
context: Context,
baseUrl: String,
certificateSHA256: String,
clazz: Class<T>,
cacheConfig: CacheConfig?,
onProgressUpdate: ((Float) -> Unit)? = null,
......@@ -43,35 +41,19 @@ object RetrofitClient {
return Retrofit.Builder()
.baseUrl(baseUrl.toHttpUrl())
.addConverterFactory(MoshiConverterFactory.create())
.client(getDefaultOKHttpClient(context, baseUrl, certificateSHA256, cacheConfig, onProgressUpdate))
.client(getDefaultOKHttpClient(context, cacheConfig, onProgressUpdate))
.build().create(clazz)
}
internal fun <T> getService(
context: Context,
baseUrl: String,
clazz: Class<T>,
cacheConfig: CacheConfig?,
onProgressUpdate: ((Float) -> Unit)? = null,
): T {
return Retrofit.Builder()
.baseUrl(baseUrl.toHttpUrl())
.addConverterFactory(MoshiConverterFactory.create())
.client(getDefaultOKHttpClient(context, baseUrl, null, cacheConfig, onProgressUpdate))
.build().create(clazz)
}
internal fun <T> getFileService(context: Context, baseUrl: String, certificateSHA256: String, clazz: Class<T>): T {
internal fun <T> getFileService(context: Context, baseUrl: String, clazz: Class<T>): T {
return Retrofit.Builder()
.baseUrl(baseUrl.toHttpUrl())
.client(getFileOKHttpClient(context, baseUrl, certificateSHA256))
.client(getFileOKHttpClient(context))
.build().create(clazz)
}
fun getDefaultOKHttpClient(
context: Context,
url: String?,
certificateSHA256: String?,
cacheConfig: CacheConfig?,
onProgressUpdate: ((Float) -> Unit)? = null,
): OkHttpClient {
......@@ -82,20 +64,10 @@ object RetrofitClient {
if (!BuildConfig.DEBUG) {
connectionSpecs(listOf(requireTls12))
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N && certificateSHA256 != null && url != null) {
certificatePinner(
CertificatePinner.Builder()
.add(url.toHttpUrl().host, certificateSHA256)
.build()
)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
.addTrustedCertificate(certificateFromString(context, "api_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "tacw_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "app_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "s3_fr_par_scw_cloud"))
.addTrustedCertificate(certificateFromString(context, "signal_api_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "ingroupe_com_isrg_root_x1"))
.addTrustedCertificate(certificateFromString(context, "ingroupe_com_r3"))
.addTrustedCertificate(certificateFromString(context, "certigna_services"))
.addTrustedCertificate(certificateFromString(context, "r3"))
.build()
sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
}
......@@ -112,7 +84,7 @@ object RetrofitClient {
}.build()
}
private fun getFileOKHttpClient(context: Context, url: String, certificateSHA256: String): OkHttpClient {
private fun getFileOKHttpClient(context: Context): OkHttpClient {
val requireTls12 = ConnectionSpec.Builder(ConnectionSpec.RESTRICTED_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build()
......@@ -121,13 +93,8 @@ object RetrofitClient {
connectionSpecs(listOf(requireTls12))
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
certificatePinner(
CertificatePinner.Builder()
.add(url.toHttpUrl().host, certificateSHA256)
.build()
)
val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
.addTrustedCertificate(certificateFromString(context, "api_tousanticovid_gouv_fr"))
.addTrustedCertificate(certificateFromString(context, "certigna_services"))
.build()
sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
}
......
......@@ -20,7 +20,6 @@ import java.io.File
class CleaDataSource(
val context: Context,
cleaReportBaseUrl: String,
cleaReportCertificateSha256: String,
private val cleaStatusFallbackBaseUrl: String,
) : RemoteCleaDataSource {
......@@ -38,7 +37,6 @@ class CleaDataSource(
private var cleaReportApi: CleaReportApi = RetrofitClient.getService(
context,
cleaReportBaseUrl,
cleaReportCertificateSha256,
CleaReportApi::class.java,
null,
)
......
......@@ -30,23 +30,20 @@ import okhttp3.RequestBody.Companion.toRequestBody
class InGroupeDatasource(
private val context: Context,
private val certificateSHA256: String,
) : RemoteCertificateDataSource {
private val okHttpClient = RetrofitClient.getDefaultOKHttpClient(
context = context,
cacheConfig = null
)
private val gson = Gson()
override suspend fun convertCertificate(
url: String,
encodedCertificate: String,
from: WalletCertificateType.Format,
to: WalletCertificateType.Format
): RobertResultData<String> {
val okHttpClient = RetrofitClient.getDefaultOKHttpClient(
context = context,
url = url,
certificateSHA256 = certificateSHA256,
cacheConfig = null
)
val gson = Gson()
val apiConvertRQ = ApiConvertRQ(chainEncoded = encodedCertificate, destination = to.toApiKey(), source = from.toApiKey())
val mediaType = "application/json".toMediaTypeOrNull()
......@@ -59,29 +56,41 @@ class InGroupeDatasource(
@Suppress("BlockingMethodInNonBlockingContext")
return withContext(Dispatchers.IO) {
val response = okHttpClient.newCall(request).execute()
val bodyRs = response.body?.string()
try {
val response = okHttpClient.newCall(request).execute()
val bodyRs = response.body?.string()
if (response.isSuccessful && bodyRs != null) {
RobertResultData.Success(bodyRs)
} else {
var analyticsErrorDesc: String? = null
try {
val error = gson.fromJson(bodyRs, ApiConvertErrorRS::class.java)
analyticsErrorDesc = "${error.msgError} (${error.codeError})"
RobertResultData.Failure(BackendException("${error.msgError} (${error.codeError})"))
} catch (e: Exception) {
RobertResultData.Failure(BackendException("Unable to parse body result: $bodyRs"))
} finally {
AnalyticsManager.reportWSError(
context,
context.filesDir,
AnalyticsServiceName.CERTIFICATE_CONVERSION,
"0",
response.code,
analyticsErrorDesc,
)
if (response.isSuccessful && bodyRs != null) {
RobertResultData.Success(bodyRs)
} else {
var analyticsErrorDesc: String? = null
try {
val error = gson.fromJson(bodyRs, ApiConvertErrorRS::class.java)
analyticsErrorDesc = "${error.msgError} (${error.codeError})"
RobertResultData.Failure(BackendException("${error.msgError} (${error.codeError})"))
} catch (e: JsonSyntaxException) {
RobertResultData.Failure(BackendException("Unable to parse body result: $bodyRs"))
} finally {
AnalyticsManager.reportWSError(
context,
context.filesDir,
AnalyticsServiceName.CERTIFICATE_CONVERSION,
"0",
response.code,
analyticsErrorDesc,
)
}
}
} catch (e: Exception) {
AnalyticsManager.reportWSError(
context,
context.filesDir,
AnalyticsServiceName.CERTIFICATE_CONVERSION,
"0",
0,
e.message,
)
RobertResultData.Failure(BackendException("Unknown error : ${e.message}"))
}
}
}
......
......@@ -36,25 +36,22 @@ import java.io.File
class ServiceDataSource(
private val context: Context,
baseUrl: String,
certificateSha256: String
) : RemoteServiceDataSource {
private var filesDir = context.filesDir
private var api: StopCovidApi = RetrofitClient.getService(context, baseUrl, certificateSha256, StopCovidApi::class.java, null)
private var api: StopCovidApi = RetrofitClient.getService(context, baseUrl, StopCovidApi::class.java, null)
private var reportProgressUpdate: ((Float) -> Unit)? = null
private var reportApi: StopCovidApi = RetrofitClient.getService(
context,
baseUrl,
certificateSha256,
StopCovidApi::class.java,
null,
) {
reportProgressUpdate?.invoke(it)
}
private var fileApi: StopCovidApi = RetrofitClient.getFileService(context, baseUrl, certificateSha256, StopCovidApi::class.java)
private var fileApi: StopCovidApi = RetrofitClient.getFileService(context, baseUrl, StopCovidApi::class.java)
override suspend fun generateCaptcha(apiVersion: String, type: String, language: String): RobertResultData<String> {
val result = RequestHelper.tryCatchRequestData(
context,
filesDir,
......
-----BEGIN CERTIFICATE-----
MIIIEjCCBfqgAwIBAgIQDlYfxFOAbxs+3Px513eHDjANBgkqhkiG9w0BAQsFADB9
MQswCQYDVQQGEwJGUjESMBAGA1UECgwJREhJTVlPVElTMRwwGgYDVQQLDBMwMDAy
IDQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQRhDBROVFJGUi00ODE0NjMwODEwMDAzNjEd
MBsGA1UEAwwUQ2VydGlnbmEgU2VydmljZXMgQ0EwHhcNMjEwMjE4MjMwMDAwWhcN
MjIwMjE4MjI1OTU5WjCBtjELMAkGA1UEBhMCRlIxDjAMBgNVBAcMBVBBUklTMUEw
PwYDVQQKDDhTRUNSRVRBUklBVCBHRU5FUkFMIE1JTklTVEVSRVMgQ0hBUkdFUyBB
RkZBSVJFUyBTT0NJQUxFUzEcMBoGA1UECwwTMDAwMiAxMzAwMDY4MDIwMDAxNjEi
MCAGA1UEAwwZYXBpLnRvdXNhbnRpY292aWQuZ291di5mcjESMBAGA1UEBRMJUzE5
MTI3MDA4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7clFLcufZ/E6
+7vOeOU8CKrrdPkIETF35MrmiZskgLCQxmOUlnZDEQmPaPP7EVKyklcTlSU6IFP0
mDqeecaR59/f8iAJXkXSNFLw6gckacOfzoCSN8HaIPdACo8WZAURI7mmhoRWjhWE
55wN8xvCmKbZESyuta4YuLnrSPaNr+h7dxybLUML1Xsfx3GW0JG2mSD6U4g8vHNc
vexmb8W4d05+8gSZ0vPoX4pldI4944gRiCMV/KpiKSUS/nb7k+txG0FCldeETAbZ
RazH+MZjaiTbNnk79tz7EWH3OKhcWOMl8i0qcjnqsLjAUhVxy9vY/fhKw4ks6Kba
dHwpgZbl1wIDAQABo4IDUjCCA04wgeQGCCsGAQUFBwEBBIHXMIHUMDYGCCsGAQUF
BzAChipodHRwOi8vYXV0b3JpdGUuY2VydGlnbmEuZnIvc2VydmljZXNjYS5kZXIw
OAYIKwYBBQUHMAKGLGh0dHA6Ly9hdXRvcml0ZS5kaGlteW90aXMuY29tL3NlcnZp
Y2VzY2EuZGVyMDAGCCsGAQUFBzABhiRodHRwOi8vc2VydmljZXNjYS5vY3NwLmRo
aW15b3Rpcy5jb20wLgYIKwYBBQUHMAGGImh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3Au
Y2VydGlnbmEuZnIwHwYDVR0jBBgwFoAUrOyGj0s3HLh/FxsZ0K7oTuM0XBIwCQYD
VR0TBAIwADBhBgNVHSAEWjBYMAgGBmeBDAECAjBMBgsqgXoBgTECBQEBATA9MDsG
CCsGAQUFBwIBFi9odHRwczovL3d3dy5jZXJ0aWduYS5jb20vYXV0b3JpdGUtY2Vy
dGlmaWNhdGlvbjBlBgNVHR8EXjBcMCugKaAnhiVodHRwOi8vY3JsLmNlcnRpZ25h
LmZyL3NlcnZpY2VzY2EuY3JsMC2gK6AphidodHRwOi8vY3JsLmRoaW15b3Rpcy5j
b20vc2VydmljZXNjYS5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/
BAQDAgWgMCQGA1UdEQQdMBuCGWFwaS50b3VzYW50aWNvdmlkLmdvdXYuZnIwHQYD
VR0OBBYEFJVxgbBC29rRySU0RhJml9w4imjcMIIBAwYKKwYBBAHWeQIEAgSB9ASB
8QDvAHYARqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUcAAAF3uV8psAAA
BAMARzBFAiA9d3rvhO80MI1H7l2l7kzzErHRybpWyr7Ec/LHRycABgIhAPP3luOT
avul4c0ADiDe7z6waL+acAi81HfNVgSfsG/KAHUAQcjKsd8iRkoQxqE6CUKHXk4x
ixsD6+tLx2jwkGKWBvYAAAF3uV8rBQAABAMARjBEAiAzmmyCixryaiOncxRtD8+x
wDv7lrE9uu9zc3ZT/kraowIgZAknCJo0HhbrATVuUJW4cGXAFZ9sahQdRwy8hROn
qQMwDQYJKoZIhvcNAQELBQADggIBAGGKS48ry8pNr+7WR1w7N2p8Qi8Bo5LPfUOA
NOCKJqtYfi0iPz6FMT5LDNNml0llgu9rWiOP7NSURWNQaPaiB0TupXuMC3/PR/1p
XZ+il8Kvetqha+0zCD56frLnlONrdTyWarnvCli3UXtnf/0X2WqkA3tMFux0sOpd
F2yR4nGSPtGSynQ9sQlkqmVFtzNfqZGEuTYOVaHK9en1Itrp5S8/JRZKBewYAvr9
30lz73ZBa7pN1FQiTjE3NxuhH1wpNDl7JKmZBMlFYihBOnnOVN8n+2LWEsYy6QWY
a+BzcXzmbZH0DpylBQGndVrx3uRLr4ZCNeTtf9HI6bccmTrsctuqpbAVUrrgs0PC
KcFiJApTQybm/sBd/0G8dRZVBewmC6Uk6Oa9zL2EeSA3xO9Wx+TSIUMIvgXlKFBb
qbVs2rTF/JdsCCxReV+PzGWF4iQpyXHslhKnItixqvzBn+StYqFCIRtI5xAu7s0V
gTQ8MD0dhKU3oFokWnON0uVka2h6syTpCfMlu6fZkfec84i9MMZ6UzhVOUUip4EA