configuration.dart 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'dart:io' as io;
  2. import 'package:flutter_secure_storage/flutter_secure_storage.dart';
  3. import 'package:path_provider/path_provider.dart';
  4. import 'package:photos/models/key_attributes.dart';
  5. import 'package:shared_preferences/shared_preferences.dart';
  6. import 'package:photos/utils/crypto_util.dart';
  7. class Configuration {
  8. Configuration._privateConstructor();
  9. static final Configuration instance = Configuration._privateConstructor();
  10. static const endpointKey = "endpoint";
  11. static const userIDKey = "user_id";
  12. static const emailKey = "email";
  13. static const tokenKey = "token";
  14. static const hasOptedForE2EKey = "has_opted_for_e2e_encryption";
  15. static const keyKey = "key";
  16. static const keyEncryptedKey = "encrypted_key";
  17. static const keyKekSalt = "kek_salt";
  18. static const keyKekHash = "kek_hash";
  19. static const keyKekHashSalt = "kek_hash_salt";
  20. static const keyEncryptedKeyIV = "encrypted_key_iv";
  21. SharedPreferences _preferences;
  22. FlutterSecureStorage _secureStorage;
  23. String _key;
  24. String _documentsDirectory;
  25. String _tempDirectory;
  26. String _thumbnailsDirectory;
  27. Future<void> init() async {
  28. _preferences = await SharedPreferences.getInstance();
  29. _secureStorage = FlutterSecureStorage();
  30. _documentsDirectory = (await getApplicationDocumentsDirectory()).path;
  31. _tempDirectory = _documentsDirectory + "/temp/";
  32. _thumbnailsDirectory = _documentsDirectory + "/thumbnails/";
  33. new io.Directory(_tempDirectory).createSync(recursive: true);
  34. new io.Directory(_thumbnailsDirectory).createSync(recursive: true);
  35. _key = await _secureStorage.read(key: keyKey);
  36. }
  37. Future<KeyAttributes> generateAndSaveKey(String passphrase) async {
  38. final key = CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
  39. final kekSalt = CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
  40. final kek = CryptoUtil.scrypt(passphrase, kekSalt, 32);
  41. final kekHashSalt =
  42. CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
  43. final kekHash = CryptoUtil.scrypt(kek, kekHashSalt, 32);
  44. final iv = CryptoUtil.getBase64EncodedSecureRandomString(length: 16);
  45. final encryptedKey = CryptoUtil.encryptToBase64(key, kek, iv);
  46. final attributes =
  47. KeyAttributes(kekSalt, kekHash, kekHashSalt, encryptedKey, iv);
  48. await setKey(key);
  49. await setKeyAttributes(attributes);
  50. return attributes;
  51. }
  52. Future<void> decryptAndSaveKey(
  53. String passphrase, KeyAttributes attributes) async {
  54. final kek = CryptoUtil.scrypt(passphrase, attributes.kekSalt, 32);
  55. bool correctPassphrase =
  56. CryptoUtil.compareHash(kek, attributes.kekHash, attributes.kekHashSalt);
  57. if (!correctPassphrase) {
  58. throw Exception("Incorrect passphrase");
  59. }
  60. final key = CryptoUtil.decryptFromBase64(
  61. attributes.encryptedKey, kek, attributes.encryptedKeyIV);
  62. await setKey(key);
  63. }
  64. String getEndpoint() {
  65. return "192.168.0.100";
  66. }
  67. String getHttpEndpoint() {
  68. if (getEndpoint() == null) {
  69. return "";
  70. }
  71. return "http://" + getEndpoint();
  72. }
  73. Future<void> setEndpoint(String endpoint) async {
  74. await _preferences.setString(endpointKey, endpoint);
  75. }
  76. String getToken() {
  77. return _preferences.getString(tokenKey);
  78. }
  79. Future<void> setToken(String token) async {
  80. await _preferences.setString(tokenKey, token);
  81. }
  82. String getEmail() {
  83. return _preferences.getString(emailKey);
  84. }
  85. Future<void> setEmail(String email) async {
  86. await _preferences.setString(emailKey, email);
  87. }
  88. int getUserID() {
  89. return _preferences.getInt(userIDKey);
  90. }
  91. Future<void> setUserID(int userID) async {
  92. await _preferences.setInt(userIDKey, userID);
  93. }
  94. Future<void> setOptInForE2E(bool hasOptedForE2E) async {
  95. await _preferences.setBool(hasOptedForE2EKey, hasOptedForE2E);
  96. }
  97. bool hasOptedForE2E() {
  98. return true;
  99. // return _preferences.getBool(hasOptedForE2EKey);
  100. }
  101. Future<void> setKeyAttributes(KeyAttributes attributes) async {
  102. await _preferences.setString(
  103. keyKekSalt, attributes == null ? null : attributes.kekSalt);
  104. await _preferences.setString(
  105. keyKekHash, attributes == null ? null : attributes.kekHash);
  106. await _preferences.setString(
  107. keyKekHashSalt, attributes == null ? null : attributes.kekHashSalt);
  108. await _preferences.setString(
  109. keyEncryptedKey, attributes == null ? null : attributes.encryptedKey);
  110. await _preferences.setString(keyEncryptedKeyIV,
  111. attributes == null ? null : attributes.encryptedKeyIV);
  112. }
  113. KeyAttributes getKeyAttributes() {
  114. if (_preferences.getString(keyEncryptedKey) == null) {
  115. return null;
  116. }
  117. return KeyAttributes(
  118. _preferences.getString(keyKekSalt),
  119. _preferences.getString(keyKekHash),
  120. _preferences.getString(keyKekHashSalt),
  121. _preferences.getString(keyEncryptedKey),
  122. _preferences.getString(keyEncryptedKeyIV));
  123. }
  124. String getEncryptedKey() {
  125. return _preferences.getString(keyEncryptedKey);
  126. }
  127. Future<void> setKey(String key) async {
  128. await _secureStorage.write(key: keyKey, value: key);
  129. _key = key;
  130. }
  131. String getKey() {
  132. return _key;
  133. }
  134. String getDocumentsDirectory() {
  135. return _documentsDirectory;
  136. }
  137. String getThumbnailsDirectory() {
  138. return _thumbnailsDirectory;
  139. }
  140. String getTempDirectory() {
  141. return _tempDirectory;
  142. }
  143. bool hasConfiguredAccount() {
  144. return getToken() != null && getKey() != null;
  145. }
  146. }