diff --git a/packages/at_client/lib/src/decryption_service/local_key_decryption.dart b/packages/at_client/lib/src/decryption_service/local_key_decryption.dart index 052877fc7..32552042e 100644 --- a/packages/at_client/lib/src/decryption_service/local_key_decryption.dart +++ b/packages/at_client/lib/src/decryption_service/local_key_decryption.dart @@ -1,3 +1,4 @@ +import 'package:at_chops/at_chops.dart'; import 'package:at_client/at_client.dart'; import 'package:at_client/src/decryption_service/decryption.dart'; import 'package:at_client/src/encryption_service/abstract_atkey_encryption.dart'; @@ -10,10 +11,12 @@ import 'package:at_utils/at_logger.dart'; class LocalKeyDecryption extends AbstractAtKeyEncryption implements AtKeyDecryption { late final AtSignLogger _logger; + late final AtClient _atClient; LocalKeyDecryption(AtClient atClient) : super(atClient) { _logger = AtSignLogger('LocalKeyDecryption (${atClient.getCurrentAtSign()})'); + _atClient = atClient; } @override @@ -23,6 +26,26 @@ class LocalKeyDecryption extends AbstractAtKeyEncryption intent: Intent.decryptData, exceptionScenario: ExceptionScenario.decryptionFailed); } + + if (atKey.key == "shared_key") { + if (atKey.sharedWith != _atClient.getCurrentAtSign()) { + throw AtKeyException( + "This symmetric shared key cannot be decrypted using your private key.", + intent: Intent.fetchData, + exceptionScenario: ExceptionScenario.decryptionFailed); + } + if (_atClient.atChops == null) { + var privateKey = + await _atClient.getLocalSecondary()!.getEncryptionPrivateKey(); + // ignore: deprecated_member_use_from_same_package + EncryptionUtil.decryptKey(encryptedValue, privateKey!); + } else { + return _atClient.atChops! + .decryptString(encryptedValue.toString(), EncryptionKeyType.rsa2048) + .result; + } + } + // Get the shared key. var symmetricKey = await getMyCopyOfSharedSymmetricKey(atKey); diff --git a/packages/at_client/lib/src/decryption_service/self_key_decryption.dart b/packages/at_client/lib/src/decryption_service/self_key_decryption.dart index 752073150..693e610db 100644 --- a/packages/at_client/lib/src/decryption_service/self_key_decryption.dart +++ b/packages/at_client/lib/src/decryption_service/self_key_decryption.dart @@ -1,3 +1,4 @@ +import 'package:at_chops/at_chops.dart'; import 'package:at_client/at_client.dart'; import 'package:at_client/src/decryption_service/decryption.dart'; import 'package:at_client/src/response/default_response_parser.dart'; @@ -8,8 +9,8 @@ import 'package:at_client/src/response/default_response_parser.dart'; /// llookup:phone.wavi@bob /// llookup:@bob:phone@bob class SelfKeyDecryption implements AtKeyDecryption { - final AtClient _atClient; SelfKeyDecryption(this._atClient); + final AtClient _atClient; @override Future decrypt(AtKey atKey, dynamic encryptedValue) async { if (encryptedValue == null || @@ -19,7 +20,26 @@ class SelfKeyDecryption implements AtKeyDecryption { intent: Intent.decryptData, exceptionScenario: ExceptionScenario.decryptionFailed); } - + if (atKey.key == "shared_key") { + if (atKey.sharedBy != _atClient.getCurrentAtSign()) { + throw AtKeyException( + "This symmetric shared key cannot be decrypted using your private key.", + intent: Intent.fetchData, + exceptionScenario: ExceptionScenario.decryptionFailed); + } + if (_atClient.atChops == null) { + var privateKey = + await _atClient.getLocalSecondary()!.getEncryptionPrivateKey(); + _atClient.encryptionService!.logger + .info(encryptedValue + " " + privateKey); + // ignore: deprecated_member_use_from_same_package + EncryptionUtil.decryptKey(encryptedValue, privateKey!); + } else { + return _atClient.atChops! + .decryptString(encryptedValue.toString(), EncryptionKeyType.rsa2048) + .result; + } + } var selfEncryptionKey = await _atClient.getLocalSecondary()!.getEncryptionSelfKey(); if ((selfEncryptionKey == null || selfEncryptionKey.isEmpty) || @@ -28,7 +48,6 @@ class SelfKeyDecryption implements AtKeyDecryption { intent: Intent.fetchSelfEncryptionKey, exceptionScenario: ExceptionScenario.fetchEncryptionKeys); } - return EncryptionUtil.decryptValue(encryptedValue, DefaultResponseParser().parse(selfEncryptionKey).response, ivBase64: atKey.metadata?.ivNonce); diff --git a/packages/at_client/lib/src/decryption_service/shared_key_decryption.dart b/packages/at_client/lib/src/decryption_service/shared_key_decryption.dart index 1c18860bd..525bffcf9 100644 --- a/packages/at_client/lib/src/decryption_service/shared_key_decryption.dart +++ b/packages/at_client/lib/src/decryption_service/shared_key_decryption.dart @@ -30,6 +30,24 @@ class SharedKeyDecryption implements AtKeyDecryption { intent: Intent.decryptData, exceptionScenario: ExceptionScenario.decryptionFailed); } + if (atKey.key == "shared_key") { + if (atKey.sharedWith != atClient.getCurrentAtSign()) { + throw AtKeyException( + "This symmetric shared key cannot be decrypted using your private key.", + intent: Intent.fetchData, + exceptionScenario: ExceptionScenario.decryptionFailed); + } + if (atClient.atChops == null) { + var privateKey = + await atClient.getLocalSecondary()!.getEncryptionPrivateKey(); + // ignore: deprecated_member_use_from_same_package + EncryptionUtil.decryptKey(encryptedValue, privateKey!); + } else { + return atClient.atChops! + .decryptString(encryptedValue.toString(), EncryptionKeyType.rsa2048) + .result; + } + } String? encryptedSharedKey; if (atKey.metadata != null && atKey.metadata!.pubKeyCS != null) { encryptedSharedKey = atKey.metadata!.sharedKeyEnc; diff --git a/packages/at_client/test/decryption_service_test.dart b/packages/at_client/test/decryption_service_test.dart index 4ac37389f..c927c0107 100644 --- a/packages/at_client/test/decryption_service_test.dart +++ b/packages/at_client/test/decryption_service_test.dart @@ -197,6 +197,22 @@ void main() { 'Failed to fetchData caused by\nConnection timeout'); } }); + + test( + 'A test to verify exception is thrown when symmetric shared key is trying to be decrypted by another atsign', + () { + var atKey = + (AtKey.shared('shared_key', namespace: 'wavi', sharedBy: '@murali') + ..sharedWith('@sitaram')) + .build(); + var sharedKeyDecryption = SharedKeyDecryption(mockAtClientImpl); + expect( + () => sharedKeyDecryption.decrypt(atKey, '123'), + throwsA(predicate((dynamic e) => + e is AtKeyException && + e.message == + 'This symmetric shared key cannot be decrypted using your private key.'))); + }); }); group('A group of test to validate the decryption service manager', () { diff --git a/tests/at_functional_test/test/atclient_putText_test.dart b/tests/at_functional_test/test/atclient_putText_test.dart index 18034d0fc..772e12e81 100644 --- a/tests/at_functional_test/test/atclient_putText_test.dart +++ b/tests/at_functional_test/test/atclient_putText_test.dart @@ -1,6 +1,7 @@ import 'package:at_client/at_client.dart'; import 'package:at_functional_test/src/at_keys_intialializer.dart'; import 'package:test/test.dart'; +import 'commit_log_compaction_test.dart'; import 'test_utils.dart'; /// The tests verify the put and get functionality where key is created using AtKey @@ -18,6 +19,16 @@ void main() { .setEncryptionKeys(atClientManager.atClient, atSign); }); + Future switchAtsigns(String atsign) async { + var preference = TestUtils.getPreference(atsign); + atClientManager.setCurrentAtSign(atsign, null, preference); + await AtEncryptionKeysLoader.getInstance() + .setEncryptionKeys(atClientManager.atClient, atSign); + var list = + await atClientManager.atClient.getRemoteSecondary()!.atLookUp.scan(); + atClientManager.atClient.encryptionService!.logger.info(list); + } + group('A group of tests to verify positive scenarios of put and get', () { test('put method - create a key sharing to other atSign', () async { // phone.wavi@alice🛠 @@ -78,4 +89,36 @@ void main() { expect(getResult.value, value); }); }); + + //////////// + group('A group of tests to verify get of symmetric shared keys', () { + test('Positive test - self keys ', () async { + var atKey = + AtKey.self("shared_key", namespace: "bob🛠", sharedBy: "@alice🛠") + .build(); + + var result = await atClientManager.atClient.get(atKey); + expect(result, returnsNormally); + }); + + test('Positive test - shared keys ', () async { + await switchAtsigns("@bob🛠"); + atClientManager.atClient.encryptionService!.logger + .info(atClientManager.atClient.getCurrentAtSign()); + var atKey = AtKey.fromString("@bob🛠:shared_key@alice🛠"); + var result = await atClientManager.atClient.get(atKey); + expect(result, returnsNormally); + }); + + test('Negative test - shared keys ', () async { + await switchAtsigns("@alice🛠"); + var atKey = (AtKey.shared("shared_key", sharedBy: "@alice🛠") + ..sharedWith("@bob🛠")) + .build(); + + expect(() async { + await atClientManager.atClient.get(atKey); + }, throwsException); + }); + }); }