MasterKeyStorageManager.kt 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* _____ _
  2. * |_ _| |_ _ _ ___ ___ _ __ __ _
  3. * | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. * |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. *
  6. * Threema for Android
  7. * Copyright (c) 2025 Threema GmbH
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. package ch.threema.localcrypto
  22. import ch.threema.common.secureContentEquals
  23. import ch.threema.localcrypto.models.MasterKeyState
  24. import ch.threema.localcrypto.models.MasterKeyStorageData
  25. import ch.threema.localcrypto.models.Version1MasterKeyStorageData
  26. import java.io.IOException
  27. import kotlin.Throws
  28. /**
  29. * Provides access to the master key storage, independently of the storage version.
  30. */
  31. class MasterKeyStorageManager(
  32. private val version2KeyFileManager: Version2MasterKeyFileManager,
  33. private val version1KeyFileManager: Version1MasterKeyFileManager,
  34. private val storageStateConverter: MasterKeyStorageStateConverter = MasterKeyStorageStateConverter(),
  35. ) {
  36. fun keyExists() = version2KeyFileManager.keyFileExists() || version1KeyFileManager.keyFileExists()
  37. @Throws(IOException::class)
  38. fun readKey(): MasterKeyState =
  39. storageStateConverter.toKeyState(readStorageData())
  40. private fun readStorageData(): MasterKeyStorageData {
  41. if (version2KeyFileManager.keyFileExists()) {
  42. return version2KeyFileManager.readKeyFile()
  43. }
  44. return version1KeyFileManager.readKeyFile()
  45. }
  46. @Throws(IOException::class)
  47. fun writeKey(data: MasterKeyState) {
  48. if (version1KeyFileManager.keyFileExists() && data is MasterKeyState.Plain) {
  49. val oldKeyData = version1KeyFileManager.readKeyFile().data
  50. if (oldKeyData is Version1MasterKeyStorageData.Unprotected) {
  51. if (!oldKeyData.masterKeyData.value.secureContentEquals(data.masterKeyData.value)) {
  52. error("Migrated master key differs from original master key")
  53. }
  54. }
  55. }
  56. version2KeyFileManager.writeKeyFile(storageStateConverter.toStorageData(data))
  57. version1KeyFileManager.deleteFile()
  58. }
  59. }