Add functionality to extract a decrypted collection key

This commit is contained in:
Vishnu Mohandas 2020-10-11 04:08:33 +05:30
parent 7e4519f9ef
commit bd879263f0
3 changed files with 55 additions and 0 deletions

View file

@ -22,11 +22,13 @@ class Configuration {
static const hasOptedForE2EKey = "has_opted_for_e2e_encryption";
static const foldersToBackUpKey = "folders_to_back_up";
static const keyKey = "key";
static const secretKeyKey = "secret_key";
static const keyAttributesKey = "key_attributes";
SharedPreferences _preferences;
FlutterSecureStorage _secureStorage;
String _key;
String _secretKey;
String _documentsDirectory;
String _tempDirectory;
String _thumbnailsDirectory;
@ -40,6 +42,7 @@ class Configuration {
new io.Directory(_tempDirectory).createSync(recursive: true);
new io.Directory(_thumbnailsDirectory).createSync(recursive: true);
_key = await _secureStorage.read(key: keyKey);
_secretKey = await _secureStorage.read(key: secretKeyKey);
}
Future<KeyAttributes> generateAndSaveKey(String passphrase) async {
@ -71,6 +74,7 @@ class Configuration {
Sodium.bin2base64(encryptedSecretKeyData.nonce),
);
await setKey(Sodium.bin2base64(key));
await setSecretKey(Sodium.bin2base64(keyPair.sk));
await setKeyAttributes(attributes);
return attributes;
}
@ -176,10 +180,23 @@ class Configuration {
}
}
Future<void> setSecretKey(String secretKey) async {
_secretKey = secretKey;
if (secretKey == null) {
await _secureStorage.delete(key: secretKeyKey);
} else {
await _secureStorage.write(key: secretKeyKey, value: secretKey);
}
}
Uint8List getKey() {
return _key == null ? null : Sodium.base642bin(_key);
}
Uint8List getSecretKey() {
return _secretKey == null ? null : Sodium.base642bin(_secretKey);
}
String getDocumentsDirectory() {
return _documentsDirectory;
}

View file

@ -1,18 +1,26 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:flutter_sodium/flutter_sodium.dart';
import 'package:logging/logging.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/db/collections_db.dart';
import 'package:photos/models/collection.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/utils/crypto_util.dart';
class CollectionsService {
final _logger = Logger("CollectionsService");
CollectionsDB _db;
Configuration _config;
UserService _userService;
CollectionsService._privateConstructor() {
_db = CollectionsDB.instance;
_config = Configuration.instance;
_userService = UserService.instance;
}
static final CollectionsService instance =
@ -46,6 +54,19 @@ class CollectionsService {
});
}
Uint8List getCollectionKey(Collection collection) {
final encryptedKey = Sodium.base642bin(collection.encryptedKey);
if (collection.ownerID == _config.getUserID()) {
return CryptoUtil.decryptSync(encryptedKey, _config.getKey(),
Sodium.base642bin(collection.keyDecryptionNonce));
} else {
return CryptoUtil.openSealSync(
encryptedKey,
Sodium.base642bin(_config.getKeyAttributes().publicKey),
_config.getSecretKey());
}
}
Future<List<Collection>> getCollections(int sinceTime) {
return Dio()
.get(

View file

@ -123,6 +123,18 @@ class CryptoUtil {
}
}
static Uint8List decryptSync(
Uint8List cipher,
Uint8List key,
Uint8List nonce,
) {
final args = Map<String, dynamic>();
args["cipher"] = cipher;
args["nonce"] = nonce;
args["key"] = key;
return cryptoSecretboxOpenEasy(args);
}
static EncryptionResult encryptChaCha(Uint8List source, Uint8List key) {
final initPushResult =
Sodium.cryptoSecretstreamXchacha20poly1305InitPush(key);
@ -205,4 +217,9 @@ class CryptoUtil {
static Future<KeyPair> generateKeyPair() async {
return Sodium.cryptoBoxKeypair();
}
static Uint8List openSealSync(
Uint8List input, Uint8List publicKey, Uint8List secretKey) {
return Sodium.cryptoBoxSealOpen(input, publicKey, secretKey);
}
}