Fix handling non-existent SVR enclaves.

This commit is contained in:
Greyson Parrelli
2025-11-04 13:59:19 -05:00
parent 2b2e3e1d02
commit 680d436038
6 changed files with 39 additions and 11 deletions

View File

@@ -215,7 +215,6 @@ android {
buildConfigField("String[]", "SIGNAL_CDSI_IPS", rootProject.extra["cdsi_ips"] as String)
buildConfigField("String[]", "SIGNAL_SVR2_IPS", rootProject.extra["svr2_ips"] as String)
buildConfigField("String", "SIGNAL_AGENT", "\"OWA\"")
buildConfigField("String", "SVR2_MRENCLAVE_LEGACY_LEGACY", "\"9314436a9a144992bb3680770ea5fd7934a7ffd29257844a33763a238903d570\"")
buildConfigField("String", "SVR2_MRENCLAVE_LEGACY", "\"093be9ea32405e85ae28dbb48eb668aebeb7dbe29517b9b86ad4bec4dfe0e6a6\"")
buildConfigField("String", "SVR2_MRENCLAVE", "\"29cd63c87bea751e3bfd0fbd401279192e2e5c99948b4ee9437eafc4968355fb\"")
buildConfigField("String[]", "UNIDENTIFIED_SENDER_TRUST_ROOTS", "new String[]{ \"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\", \"BUkY0I+9+oPgDCn4+Ac6Iu813yvqkDr/ga8DzLxFxuk6\"}")
@@ -402,7 +401,6 @@ android {
buildConfigField("String", "SIGNAL_CDN3_URL", "\"https://cdn3-staging.signal.org\"")
buildConfigField("String", "SIGNAL_CDSI_URL", "\"https://cdsi.staging.signal.org\"")
buildConfigField("String", "SIGNAL_SVR2_URL", "\"https://svr2.staging.signal.org\"")
buildConfigField("String", "SVR2_MRENCLAVE_LEGACY_LEGACY", "\"38e01eff4fe357dc0b0e8ef7a44b4abc5489fbccba3a78780f3872c277f62bf3\"")
buildConfigField("String", "SVR2_MRENCLAVE_LEGACY", "\"2e8cefe6e3f389d8426adb24e9b7fb7adf10902c96f06f7bbcee36277711ed91\"")
buildConfigField("String", "SVR2_MRENCLAVE", "\"a75542d82da9f6914a1e31f8a7407053b99cc99a0e7291d8fbd394253e19b036\"")
buildConfigField("String[]", "UNIDENTIFIED_SENDER_TRUST_ROOTS", "new String[]{\"BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx\", \"BYhU6tPjqP46KGZEzRs1OL4U39V5dlPJ/X09ha4rErkm\"}")

View File

@@ -68,6 +68,10 @@ class PinRestoreViewModel : ViewModel() {
is SecureValueRecovery.RestoreResponse.ApplicationError -> {
event.postValue(Event.NETWORK_ERROR)
}
SecureValueRecovery.RestoreResponse.EnclaveNotFound -> {
event.postValue(Event.PIN_LOCKED)
}
}
}
}

View File

@@ -44,7 +44,6 @@ object SvrRepository {
val TAG = Log.tag(SvrRepository::class.java)
private val svr2LegacyLegacy: SecureValueRecovery = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE_LEGACY_LEGACY)
private val svr2Legacy: SecureValueRecovery = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE_LEGACY)
private val svr2: SecureValueRecovery = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE)
private val svr3: SecureValueRecovery = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV3(AppDependencies.libsignalNetwork)
@@ -53,7 +52,7 @@ object SvrRepository {
private val readImplementations: List<SecureValueRecovery> = if (Svr3Migration.shouldReadFromSvr3) {
listOf(svr3, svr2)
} else {
listOf(svr2, svr2Legacy, svr2LegacyLegacy)
listOf(svr2, svr2Legacy)
}
/** An ordered list of SVR implementations to write to. They should be in priority order, with the most important one listed first. */
@@ -66,7 +65,6 @@ object SvrRepository {
if (Svr3Migration.shouldWriteToSvr2) {
implementations += svr2
implementations += svr2Legacy
implementations += svr2LegacyLegacy
}
return implementations
}
@@ -104,8 +102,7 @@ object SvrRepository {
} else {
listOf(
svr2 to { restoreMasterKeyPreRegistrationFromV2(svr2, credentials.svr2, userPin) },
svr2Legacy to { restoreMasterKeyPreRegistrationFromV2(svr2Legacy, credentials.svr2, userPin) },
svr2LegacyLegacy to { restoreMasterKeyPreRegistrationFromV2(svr2LegacyLegacy, credentials.svr2, userPin) }
svr2Legacy to { restoreMasterKeyPreRegistrationFromV2(svr2Legacy, credentials.svr2, userPin) }
)
}
@@ -140,6 +137,10 @@ object SvrRepository {
RestoreResponse.Missing -> {
Log.w(TAG, "[restoreMasterKeyPreRegistration] No data found for $implementation | Continuing to next implementation.", true)
}
RestoreResponse.EnclaveNotFound -> {
Log.w(TAG, "[restoreMasterKeyPreRegistration] Enclave no longer exists: $implementation | Continuing to next implementation.", true)
}
}
}
@@ -218,6 +219,10 @@ object SvrRepository {
RestoreResponse.Missing -> {
Log.w(TAG, "[restoreMasterKeyPostRegistration] No data found for: $implementation | Continuing to next implementation.", true)
}
RestoreResponse.EnclaveNotFound -> {
Log.w(TAG, "[restoreMasterKeyPostRegistration] Enclave no longer exists: $implementation | Continuing to next implementation.", true)
}
}
}

View File

@@ -103,6 +103,9 @@ interface SecureValueRecovery {
/** The PIN was incorrect. Includes the number of attempts the user has remaining. */
data class PinMismatch(val triesRemaining: Int) : RestoreResponse()
/** The enclave no longer exists */
data object EnclaveNotFound : RestoreResponse()
/** There as a network error. Not a bad response, but rather interference or some other inability to make a network request. */
data class NetworkError(val exception: IOException) : RestoreResponse()

View File

@@ -83,7 +83,11 @@ class SecureValueRecoveryV2(
DeleteResponse.Success
} catch (e: NonSuccessfulResponseCodeException) {
Log.w(TAG, "[Delete] Failed with a non-successful response code exception!", e)
DeleteResponse.ApplicationError(e)
if (e.code == 404) {
DeleteResponse.EnclaveNotFound
} else {
DeleteResponse.ApplicationError(e)
}
} catch (e: IOException) {
Log.w(TAG, "[Delete] Failed with a network exception!", e)
DeleteResponse.NetworkError(e)
@@ -149,7 +153,11 @@ class SecureValueRecoveryV2(
}
} catch (e: NonSuccessfulResponseCodeException) {
Log.w(TAG, "[Restore] Failed with a non-successful response code exception!", e)
RestoreResponse.ApplicationError(e)
if (e.code == 404) {
RestoreResponse.EnclaveNotFound
} else {
RestoreResponse.ApplicationError(e)
}
} catch (e: IOException) {
Log.w(TAG, "[Restore] Failed with a network exception!", e)
RestoreResponse.NetworkError(e)
@@ -212,7 +220,11 @@ class SecureValueRecoveryV2(
}
} catch (e: NonSuccessfulResponseCodeException) {
Log.w(TAG, "[Set] Failed with a non-successful response code exception!", e)
BackupResponse.ApplicationError(e)
if (e.code == 404) {
BackupResponse.EnclaveNotFound
} else {
BackupResponse.ApplicationError(e)
}
} catch (e: IOException) {
Log.w(TAG, "[Set] Failed with a network exception!", e)
BackupResponse.NetworkError(e)

View File

@@ -149,7 +149,13 @@ internal class Svr2Socket(
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: OkHttpResponse?) {
if (emitError(IOException(t))) {
val exception = if (t.message?.contains("404") == true) {
NonSuccessfulResponseCodeException(404)
} else {
IOException(t)
}
if (emitError(exception)) {
Log.w(TAG, "[onFailure] response? " + (response != null), t)
stage.set(Stage.FAILED)
webSocket.close(1000, "OK")