LCOV - code coverage report
Current view: top level - service - encryption_service.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 0 241 0.0 %
Date: 2022-01-19 17:54:05 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:async';
       2             : import 'dart:convert';
       3             : import 'dart:typed_data';
       4             : 
       5             : import 'package:at_client/at_client.dart';
       6             : import 'package:at_commons/at_builders.dart';
       7             : import 'package:at_commons/at_commons.dart';
       8             : import 'package:at_lookup/at_lookup.dart';
       9             : import 'package:at_utils/at_logger.dart';
      10             : import 'package:crypton/crypton.dart';
      11             : 
      12             : class EncryptionService {
      13             :   RemoteSecondary? remoteSecondary;
      14             : 
      15             :   LocalSecondary? localSecondary;
      16             : 
      17             :   String? currentAtSign;
      18             : 
      19             :   var logger = AtSignLogger('EncryptionService');
      20             : 
      21           0 :   Future<String> encrypt(String? key, String value, String sharedWith) async {
      22             :     var isSharedKeyAvailable = false;
      23             :     var currentAtSignPublicKey =
      24           0 :         await localSecondary!.getEncryptionPublicKey(currentAtSign!);
      25             :     var currentAtSignPrivateKey =
      26           0 :         await localSecondary!.getEncryptionPrivateKey();
      27           0 :     var sharedWithUser = sharedWith.replaceFirst('@', '');
      28             : 
      29             :     //1. Get/Generate AES key for sharedWith atsign
      30           0 :     var llookupVerbBuilder = LLookupVerbBuilder()
      31           0 :       ..atKey = '$AT_ENCRYPTION_SHARED_KEY.$sharedWithUser'
      32           0 :       ..sharedBy = currentAtSign;
      33             :     String? sharedKey;
      34             :     try {
      35           0 :       sharedKey = await localSecondary!.executeVerb(llookupVerbBuilder);
      36           0 :     } on KeyNotFoundException {
      37           0 :       logger.finer(
      38           0 :           '${llookupVerbBuilder.atKey}$currentAtSign not found in local secondary. Fetching from cloud secondary.');
      39             :     }
      40             :     // If sharedKey is not found in localSecondary, search in remote secondary.
      41             :     try {
      42           0 :       if (sharedKey == null || sharedKey == 'data:null') {
      43           0 :         sharedKey = await remoteSecondary!.executeVerb(llookupVerbBuilder);
      44             :       }
      45           0 :     } on AtLookUpException {
      46           0 :       logger.finer(
      47           0 :           '${llookupVerbBuilder.atKey}$currentAtSign not found in remote secondary. Generating a new shared key');
      48             :     }
      49             :     // If sharedKey is null, generate a new sharedKey,
      50             :     // Else decrypt the existing shared key.
      51           0 :     if (sharedKey == null || sharedKey == 'data:null') {
      52           0 :       logger.finer('Generated a AES Key for $sharedWithUser');
      53           0 :       sharedKey = EncryptionUtil.generateAESKey();
      54             :     } else {
      55             :       isSharedKeyAvailable = true;
      56           0 :       sharedKey = sharedKey.replaceFirst('data:', '');
      57             :       sharedKey =
      58           0 :           EncryptionUtil.decryptKey(sharedKey, currentAtSignPrivateKey!);
      59             :     }
      60             :     //2. Verify if encryptedSharedKey for sharedWith atSign is available.
      61           0 :     var lookupEncryptionSharedKey = LLookupVerbBuilder()
      62           0 :       ..sharedWith = sharedWith
      63           0 :       ..sharedBy = currentAtSign
      64           0 :       ..atKey = AT_ENCRYPTION_SHARED_KEY;
      65             :     String? result;
      66             :     try {
      67           0 :       result = await localSecondary!.executeVerb(lookupEncryptionSharedKey);
      68           0 :     } on KeyNotFoundException {
      69           0 :       logger.finer(
      70           0 :           '$sharedWith:$AT_ENCRYPTION_SHARED_KEY@$currentAtSign not found in local secondary. Fetching from cloud secondary');
      71             :     }
      72             : 
      73             :     //3. Create the encryptedSharedKey if
      74             :     // a. encryptedSharedKey not available (or)
      75             :     // b. If the sharedKey is changed.
      76           0 :     if (result == null || result == 'data:null' || !isSharedKeyAvailable) {
      77             :       var sharedWithPublicKey;
      78             :       try {
      79           0 :         sharedWithPublicKey = await _getSharedWithPublicKey(sharedWithUser);
      80           0 :       } on Exception {
      81             :         rethrow;
      82             :       }
      83             :       //Encrypt shared key with public key of sharedWith atsign.
      84             :       var encryptedSharedKey =
      85           0 :           EncryptionUtil.encryptKey(sharedKey, sharedWithPublicKey);
      86             :       // Store the encryptedSharedWith Key. Set ttr to enable sharedWith atsign to cache the encryptedSharedKey.
      87           0 :       var updateSharedKeyBuilder = UpdateVerbBuilder()
      88           0 :         ..sharedWith = sharedWith
      89           0 :         ..sharedBy = currentAtSign
      90           0 :         ..atKey = AT_ENCRYPTION_SHARED_KEY
      91           0 :         ..value = encryptedSharedKey
      92           0 :         ..ttr = 3888000;
      93           0 :       await localSecondary!.executeVerb(updateSharedKeyBuilder, sync: true);
      94             :     }
      95             : 
      96             :     //4. Store the sharedKey for future retrival.
      97             :     if (!isSharedKeyAvailable) {
      98             :       // Encrypt the sharedKey with currentAtSign Public key and store it.
      99             :       var encryptedSharedKeyForCurrentAtSign =
     100           0 :           EncryptionUtil.encryptKey(sharedKey, currentAtSignPublicKey!);
     101             : 
     102           0 :       var updateSharedKeyForCurrentAtSignBuilder = UpdateVerbBuilder()
     103           0 :         ..sharedBy = currentAtSign
     104           0 :         ..atKey = '$AT_ENCRYPTION_SHARED_KEY.$sharedWithUser'
     105           0 :         ..value = encryptedSharedKeyForCurrentAtSign;
     106           0 :       await localSecondary!
     107           0 :           .executeVerb(updateSharedKeyForCurrentAtSignBuilder, sync: true);
     108             :     }
     109             : 
     110             :     //5. Encrypt value using sharedKey
     111           0 :     var encryptedValue = EncryptionUtil.encryptValue(value, sharedKey);
     112             :     return encryptedValue;
     113             :   }
     114             : 
     115             :   /// Returns the decrypted value for the given encrypted value.
     116             :   /// Throws [IllegalArgumentException] if encrypted value is null.
     117             :   /// Throws [KeyNotFoundException] if encryption keys are not found.
     118           0 :   Future<String> decrypt(String encryptedValue, String sharedBy) async {
     119           0 :     if (encryptedValue == null || encryptedValue.isEmpty) {
     120           0 :       throw IllegalArgumentException(
     121             :           'Decryption failed. Encrypted value is null');
     122             :     }
     123           0 :     sharedBy = sharedBy.replaceFirst('@', '');
     124             :     var encryptedSharedKey;
     125             :     //1. Get encrypted shared key
     126           0 :     encryptedSharedKey = await _getEncryptedSharedKey(sharedBy);
     127           0 :     if (encryptedSharedKey == 'null' || encryptedSharedKey.isEmpty) {
     128           0 :       throw KeyNotFoundException('encrypted Shared key not found');
     129             :     }
     130             : 
     131             :     //2. decrypt shared key using private key
     132             :     var currentAtSignPrivateKey =
     133           0 :         await (localSecondary!.getEncryptionPrivateKey());
     134             :     if (currentAtSignPrivateKey == null) {
     135           0 :       throw KeyNotFoundException('encryption private not found');
     136             :     }
     137             :     var sharedKey =
     138           0 :         EncryptionUtil.decryptKey(encryptedSharedKey, currentAtSignPrivateKey);
     139             : 
     140             :     //3. decrypt value using shared key
     141           0 :     var decryptedValue = EncryptionUtil.decryptValue(encryptedValue, sharedKey);
     142             :     return decryptedValue;
     143             :   }
     144             : 
     145             :   ///Returns `decrypted value` on successful decryption.
     146             :   /// Used for local lookup @bob:phone@alice
     147             :   /// Throws [IllegalArgumentException] if encrypted value is null.
     148           0 :   Future<String?> decryptLocal(String? encryptedValue, String? currentAtSign,
     149             :       String sharedWithUser) async {
     150           0 :     if (encryptedValue == null || encryptedValue.isEmpty) {
     151           0 :       throw IllegalArgumentException(
     152             :           'Decryption failed. Encrypted value is null');
     153             :     }
     154           0 :     sharedWithUser = sharedWithUser.replaceFirst('@', '');
     155             :     var currentAtSignPrivateKey =
     156           0 :         await localSecondary!.getEncryptionPrivateKey();
     157           0 :     var llookupVerbBuilder = LLookupVerbBuilder()
     158           0 :       ..atKey = '$AT_ENCRYPTION_SHARED_KEY.$sharedWithUser'
     159           0 :       ..sharedBy = currentAtSign;
     160           0 :     var sharedKey = await localSecondary!.executeVerb(llookupVerbBuilder);
     161             :     if (sharedKey == null) {
     162           0 :       logger.severe('Decryption failed. SharedKey is null');
     163           0 :       throw AtClientException('AT0014', 'Decryption failed. SharedKey is null');
     164             :     }
     165             :     //trying to llookup a value without shared key. throw exception or return null}
     166           0 :     sharedKey = sharedKey.replaceFirst('data:', '');
     167             :     var decryptedSharedKey =
     168           0 :         EncryptionUtil.decryptKey(sharedKey, currentAtSignPrivateKey!);
     169             :     var decryptedValue =
     170           0 :         EncryptionUtil.decryptValue(encryptedValue, decryptedSharedKey);
     171             : 
     172             :     return decryptedValue;
     173             :   }
     174             : 
     175             :   /// returns encrypted value
     176           0 :   Future<String?> encryptForSelf(String? key, String value) async {
     177             :     try {
     178             :       // //1. Get AES key for current atsign
     179           0 :       var selfEncryptionKey = await _getSelfEncryptionKey();
     180           0 :       if (selfEncryptionKey == null || selfEncryptionKey == 'data:null') {
     181           0 :         throw Exception(
     182           0 :             'Self encryption key is not set for atsign $currentAtSign');
     183             :       } else {
     184           0 :         selfEncryptionKey = selfEncryptionKey.replaceFirst('data:', '');
     185             :       }
     186             : 
     187             :       // Encrypt value using sharedKey
     188             :       var encryptedValue =
     189           0 :           EncryptionUtil.encryptValue(value, selfEncryptionKey);
     190             :       return encryptedValue;
     191           0 :     } on Exception catch (e) {
     192           0 :       logger.severe(
     193           0 :           'Exception while encrypting value for key $key: ${e.toString()}');
     194             :       return null;
     195             :     }
     196             :   }
     197             : 
     198             :   /// Returns decrypted value
     199             :   /// Used for local lookup @alice:phone@alice
     200             :   /// Throws [IllegalArgumentException] if encrypted value is null.
     201           0 :   Future<String?> decryptForSelf(
     202             :       String? encryptedValue, bool isEncrypted) async {
     203           0 :     if (encryptedValue == null || encryptedValue == 'null') {
     204           0 :       throw IllegalArgumentException(
     205             :           'Decryption failed. Encrypted value is null');
     206             :     }
     207             :     if (!isEncrypted) {
     208           0 :       logger.info(
     209             :           'isEncrypted is set to false, Returning the original value without decrypting');
     210             :       return encryptedValue;
     211             :     }
     212             :     try {
     213           0 :       var selfEncryptionKey = await _getSelfEncryptionKey();
     214           0 :       if (selfEncryptionKey == null || selfEncryptionKey == 'data:null') {
     215             :         return encryptedValue;
     216             :       }
     217           0 :       selfEncryptionKey = selfEncryptionKey.toString().replaceAll('data:', '');
     218             :       // decrypt value using self encryption key
     219             :       var decryptedValue =
     220           0 :           EncryptionUtil.decryptValue(encryptedValue, selfEncryptionKey);
     221             :       return decryptedValue;
     222           0 :     } on Exception catch (e) {
     223           0 :       logger.severe('Exception while decrypting value: ${e.toString()}');
     224             :       return null;
     225           0 :     } on Error catch (e) {
     226           0 :       logger.severe('Exception while decrypting value: ${e.toString()}');
     227             :       return null;
     228             :     }
     229             :   }
     230             : 
     231             :   //TODO remove code duplication - encrypt and encryptStream
     232           0 :   Future<List<int>> encryptStream(List<int> value, String sharedWith) async {
     233             :     var currentAtSignPublicKey =
     234           0 :         await (localSecondary!.getEncryptionPublicKey(currentAtSign!));
     235             :     var currentAtSignPrivateKey =
     236           0 :         await localSecondary!.getEncryptionPrivateKey();
     237           0 :     var sharedWithUser = sharedWith.replaceFirst('@', '');
     238             :     // //1. Get/Generate AES key for sharedWith atsign
     239           0 :     var llookupVerbBuilder = LLookupVerbBuilder()
     240           0 :       ..atKey = '$AT_ENCRYPTION_SHARED_KEY.$sharedWithUser'
     241           0 :       ..sharedBy = currentAtSign;
     242             :     String? sharedKey;
     243             :     try {
     244           0 :       sharedKey = await localSecondary!.executeVerb(llookupVerbBuilder);
     245           0 :     } on KeyNotFoundException {
     246           0 :       logger.finer('${llookupVerbBuilder.atKey} not found in local secondary');
     247             :     }
     248           0 :     if (sharedKey == null || sharedKey == 'data:null') {
     249           0 :       sharedKey = EncryptionUtil.generateAESKey();
     250             :     } else {
     251           0 :       sharedKey = sharedKey.replaceFirst('data:', '');
     252             :       sharedKey =
     253           0 :           EncryptionUtil.decryptKey(sharedKey, currentAtSignPrivateKey!);
     254             :     }
     255             :     //2. Lookup public key of sharedWith atsign
     256           0 :     var plookupBuilder = PLookupVerbBuilder()
     257           0 :       ..atKey = 'publickey'
     258           0 :       ..sharedBy = sharedWith;
     259             :     var sharedWithPublicKey =
     260           0 :         await remoteSecondary!.executeAndParse(plookupBuilder);
     261           0 :     if (sharedWithPublicKey == 'null' || sharedWithPublicKey.isEmpty) {
     262           0 :       throw KeyNotFoundException(
     263             :           'shared key not found. data sharing is forbidden.');
     264             :     }
     265             :     //3. Encrypt shared key with public key of sharedWith atsign and store
     266             :     var encryptedSharedKey =
     267           0 :         EncryptionUtil.encryptKey(sharedKey, sharedWithPublicKey);
     268             : 
     269           0 :     var updateSharedKeyBuilder = UpdateVerbBuilder()
     270           0 :       ..sharedWith = sharedWith
     271           0 :       ..sharedBy = currentAtSign
     272           0 :       ..atKey = AT_ENCRYPTION_SHARED_KEY
     273           0 :       ..value = encryptedSharedKey;
     274           0 :     await localSecondary!.executeVerb(updateSharedKeyBuilder, sync: true);
     275             : 
     276             :     //4. Store the shared key for future retrieval
     277             :     if (currentAtSignPublicKey == null) {
     278           0 :       throw KeyNotFoundException('encryption public key not found');
     279             :     }
     280             :     var encryptedSharedKeyForCurrentAtSign =
     281           0 :         EncryptionUtil.encryptKey(sharedKey, currentAtSignPublicKey);
     282             : 
     283           0 :     var updateSharedKeyForCurrentAtSignBuilder = UpdateVerbBuilder()
     284           0 :       ..sharedBy = currentAtSign
     285           0 :       ..atKey = '$AT_ENCRYPTION_SHARED_KEY.$sharedWithUser'
     286           0 :       ..value = encryptedSharedKeyForCurrentAtSign;
     287           0 :     await localSecondary!
     288           0 :         .executeVerb(updateSharedKeyForCurrentAtSignBuilder, sync: true);
     289             : 
     290             :     //5. Encrypt value using sharedKey
     291           0 :     var encryptedValue = EncryptionUtil.encryptBytes(value, sharedKey);
     292             :     return encryptedValue;
     293             :   }
     294             : 
     295           0 :   List<int> decryptStream(List<int> encryptedValue, String sharedKey) {
     296             :     //decrypt stream using decrypted aes shared key
     297           0 :     var decryptedValue = EncryptionUtil.decryptBytes(encryptedValue, sharedKey);
     298             :     return decryptedValue;
     299             :   }
     300             : 
     301           0 :   Future<bool> verifyPublicDataSignature(
     302             :       String sharedBy, String dataSignature, String value) async {
     303           0 :     var cachedPublicKeyBuilder = LLookupVerbBuilder()
     304           0 :       ..atKey = 'publickey.$sharedBy'
     305           0 :       ..sharedBy = currentAtSign;
     306             :     String? sharedByPublicKey;
     307             :     try {
     308             :       sharedByPublicKey =
     309           0 :           await localSecondary!.executeVerb(cachedPublicKeyBuilder);
     310           0 :     } on KeyNotFoundException {
     311           0 :       logger.finer(
     312           0 :           '${cachedPublicKeyBuilder.atKey} not found in local secondary');
     313             :     }
     314           0 :     if (sharedByPublicKey == null || sharedByPublicKey == 'data:null') {
     315           0 :       var plookupBuilder = PLookupVerbBuilder()
     316           0 :         ..atKey = 'publickey'
     317           0 :         ..sharedBy = sharedBy;
     318             :       sharedByPublicKey =
     319           0 :           await remoteSecondary!.executeAndParse(plookupBuilder);
     320             :       //4.b store sharedWith public key for future retrieval
     321           0 :       var sharedWithPublicKeyBuilder = UpdateVerbBuilder()
     322           0 :         ..atKey = 'publickey.$sharedBy'
     323           0 :         ..sharedBy = currentAtSign
     324           0 :         ..value = sharedByPublicKey;
     325           0 :       await localSecondary!
     326           0 :           .executeVerb(sharedWithPublicKeyBuilder, sync: false);
     327             :     } else {
     328           0 :       sharedByPublicKey = sharedByPublicKey.replaceFirst('data:', '');
     329             :     }
     330             : //    if (sharedByPublicKey == null) {
     331             : //      logger.severe('unable to verify public data sharedBy: $sharedBy');
     332             : //      return false;
     333             : //    }
     334           0 :     var publicKey = RSAPublicKey.fromString(sharedByPublicKey);
     335           0 :     var isDataValid = publicKey.verifySHA256Signature(
     336           0 :         utf8.encode(value) as Uint8List, base64Decode(dataSignature));
     337             :     return isDataValid;
     338             :   }
     339             : 
     340           0 :   String signPublicData(String encryptionPrivateKey, dynamic value) {
     341           0 :     var privateKey = RSAPrivateKey.fromString(encryptionPrivateKey);
     342             :     var dataSignature =
     343           0 :         privateKey.createSHA256Signature(utf8.encode(value) as Uint8List);
     344           0 :     return base64Encode(dataSignature);
     345             :   }
     346             : 
     347             :   @Deprecated('Not in use')
     348           0 :   Future<void> encryptUnencryptedData() async {
     349           0 :     var atClient = await (AtClientImpl.getClient(currentAtSign));
     350             :     if (atClient == null) {
     351             :       return;
     352             :     }
     353           0 :     var selfKeys = await atClient.getAtKeys(sharedBy: currentAtSign);
     354           0 :     selfKeys.forEach((atKey) async {
     355           0 :       var key = atKey.key!;
     356           0 :       if (!(key.startsWith(AT_PKAM_PRIVATE_KEY) ||
     357           0 :           key.startsWith(AT_PKAM_PUBLIC_KEY) ||
     358           0 :           key.startsWith(AT_ENCRYPTION_PRIVATE_KEY) ||
     359           0 :           key.startsWith(AT_SIGNING_PRIVATE_KEY) ||
     360           0 :           key.startsWith(AT_ENCRYPTION_SHARED_KEY) ||
     361           0 :           key.startsWith('_'))) {
     362           0 :         var sharedWith = atKey.sharedWith;
     363             :         var isPublic = false;
     364             :         var isCached = false;
     365           0 :         if (atKey.metadata != null) {
     366           0 :           isPublic = atKey.metadata?.isPublic ?? false;
     367           0 :           isCached = atKey.metadata?.isCached ?? false;
     368             :         }
     369             :         if (!isPublic && !isCached) {
     370           0 :           if (sharedWith == null || sharedWith == currentAtSign) {
     371           0 :             var atValue = await atClient.get(atKey);
     372             :             var metadata =
     373           0 :                 (atValue.metadata != null) ? atValue.metadata! : Metadata();
     374             :             var isEncrypted =
     375           0 :                 (metadata.isEncrypted != null) ? metadata.isEncrypted! : false;
     376             :             if (!isEncrypted) {
     377           0 :               var value = atValue.value;
     378           0 :               metadata.isEncrypted = true;
     379           0 :               metadata.isBinary =
     380           0 :                   (metadata.isBinary != null) ? metadata.isBinary : false;
     381           0 :               atKey.metadata = metadata;
     382           0 :               await atClient.put(atKey, value);
     383             :             }
     384             :           }
     385             :         }
     386             :       }
     387             :     });
     388           0 :     await atClient.getSyncManager()!.sync();
     389             :   }
     390             : 
     391           0 :   Future<String?> _getSelfEncryptionKey() async {
     392           0 :     var selfEncryptionKey = await localSecondary!.getEncryptionSelfKey();
     393             :     return selfEncryptionKey;
     394             :   }
     395             : 
     396             :   /// Returns sharedWith atSign publicKey.
     397             :   /// Throws [KeyNotFoundException] if sharedWith atSign publicKey is not found.
     398           0 :   Future<String?> _getSharedWithPublicKey(String sharedWithUser) async {
     399             :     //a local lookup the cached public key of sharedWith atsign.
     400             :     String? sharedWithPublicKey;
     401           0 :     var cachedPublicKeyBuilder = LLookupVerbBuilder()
     402           0 :       ..atKey = 'publickey.$sharedWithUser'
     403           0 :       ..sharedBy = currentAtSign;
     404             :     try {
     405             :       sharedWithPublicKey =
     406           0 :           await localSecondary!.executeVerb(cachedPublicKeyBuilder);
     407           0 :     } on KeyNotFoundException {
     408           0 :       logger.finer(
     409           0 :           '${cachedPublicKeyBuilder.atKey}@$currentAtSign not found in local secondary. Fetching from cloud secondary');
     410             :     }
     411           0 :     if (sharedWithPublicKey != null && sharedWithPublicKey != 'data:null') {
     412             :       sharedWithPublicKey =
     413           0 :           sharedWithPublicKey.toString().replaceAll('data:', '');
     414             :       return sharedWithPublicKey;
     415             :     }
     416             : 
     417             :     //b Lookup public key of sharedWith atsign
     418           0 :     var plookupBuilder = PLookupVerbBuilder()
     419           0 :       ..atKey = 'publickey'
     420           0 :       ..sharedBy = sharedWithUser;
     421             :     sharedWithPublicKey =
     422           0 :         await remoteSecondary!.executeAndParse(plookupBuilder);
     423             : 
     424             :     // If SharedWith PublicKey is not found throw KeyNotFoundException.
     425           0 :     if (sharedWithPublicKey == 'null' || sharedWithPublicKey.isEmpty) {
     426           0 :       throw KeyNotFoundException(
     427             :           'public key not found. data sharing is forbidden.');
     428             :     }
     429             :     //Cache the sharedWithPublicKey
     430           0 :     var sharedWithPublicKeyBuilder = UpdateVerbBuilder()
     431           0 :       ..atKey = 'publickey.$sharedWithUser'
     432           0 :       ..sharedBy = currentAtSign
     433           0 :       ..value = sharedWithPublicKey;
     434           0 :     await localSecondary!.executeVerb(sharedWithPublicKeyBuilder, sync: true);
     435             :     return sharedWithPublicKey;
     436             :   }
     437             : 
     438           0 :   Future<String?> _getEncryptedSharedKey(String sharedBy) async {
     439             :     String? encryptedSharedKey;
     440           0 :     var localLookupSharedKeyBuilder = LLookupVerbBuilder()
     441           0 :       ..isCached = true
     442           0 :       ..sharedBy = sharedBy
     443           0 :       ..sharedWith = currentAtSign
     444           0 :       ..atKey = AT_ENCRYPTION_SHARED_KEY;
     445             :     try {
     446             :       encryptedSharedKey =
     447           0 :           await localSecondary!.executeVerb(localLookupSharedKeyBuilder);
     448           0 :     } on KeyNotFoundException {
     449           0 :       logger.finer(
     450           0 :           '$sharedBy:${localLookupSharedKeyBuilder.atKey}@$currentAtSign not found in local secondary. Fetching from cloud secondary');
     451             :     }
     452           0 :     if (encryptedSharedKey == null || encryptedSharedKey == 'data:null') {
     453           0 :       var sharedKeyLookUpBuilder = LookupVerbBuilder()
     454           0 :         ..atKey = AT_ENCRYPTION_SHARED_KEY
     455           0 :         ..sharedBy = sharedBy
     456           0 :         ..auth = true;
     457             :       encryptedSharedKey =
     458           0 :           await remoteSecondary!.executeAndParse(sharedKeyLookUpBuilder);
     459             :     }
     460           0 :     if (encryptedSharedKey.isNotEmpty) {
     461           0 :       encryptedSharedKey = encryptedSharedKey.replaceFirst('data:', '');
     462             :     }
     463             :     return encryptedSharedKey;
     464             :   }
     465             : 
     466           0 :   Future<String> getSharedKey(String sharedBy) async {
     467           0 :     sharedBy = sharedBy.replaceFirst('@', '');
     468             : 
     469           0 :     var encryptedSharedKey = await _getEncryptedSharedKey(sharedBy);
     470           0 :     if (encryptedSharedKey == null || encryptedSharedKey == 'null') {
     471           0 :       throw KeyNotFoundException('encrypted Shared key not found');
     472             :     }
     473             :     //2. decrypt shared key using private key
     474             :     var currentAtSignPrivateKey =
     475           0 :         await (localSecondary!.getEncryptionPrivateKey());
     476             :     if (currentAtSignPrivateKey == null) {
     477           0 :       throw KeyNotFoundException('private encryption key not found');
     478             :     }
     479             :     var sharedKey =
     480           0 :         EncryptionUtil.decryptKey(encryptedSharedKey, currentAtSignPrivateKey);
     481             :     return sharedKey;
     482             :   }
     483             : 
     484           0 :   String generateFileEncryptionKey() {
     485           0 :     return EncryptionUtil.generateAESKey();
     486             :   }
     487             : 
     488           0 :   List<int> encryptFile(List<int> fileContent, String fileEncryptionKey) {
     489           0 :     return EncryptionUtil.encryptBytes(fileContent, fileEncryptionKey);
     490             :   }
     491             : 
     492           0 :   List<int> decryptFile(List<int> fileContent, String decryptionKey) {
     493             :     var encryptedValue =
     494           0 :         EncryptionUtil.decryptBytes(fileContent, decryptionKey);
     495             :     return encryptedValue;
     496             :   }
     497             : }

Generated by: LCOV version 1.13