encryptFile method

Future<void> encryptFile(
  1. String filePath,
  2. String fileName
)

Encrypt a file content The function takes all the content in a file and encrypt them using the key and store the ciphertext in the same file

Implementation

Future<void> encryptFile(String filePath, String fileName) async {
  /// Encryption file URL
  String encFileUrl =
      webId.replaceAll('profile/card#me', filePath + '/' + fileName);

  /// Get plaintext file content
  String fileContent = await fetchFile(filePath + '/' + fileName);

  /// Get encryption key that is stored in the local storage
  String encKey = appStorage.getItem('encKey');

  /// Encrypt the plaintext file content
  List encryptValRes = encryptVal(encKey, fileContent);
  String encryptValStr = encryptValRes[0];
  String ivValStr = encryptValRes[1];

  /// Delete the existing file with plaintext and create a new file with ciphertext
  String delResponse = await deleteItem(false, filePath + '/' + fileName);

  if (delResponse == 'ok') {
    String dPopToken =
        genDpopToken(encFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
    String insertQuery =
        genSparqlQuery('INSERT', '', encValPred, encryptValStr);
    String insertResponse =
        await runQuery(encFileUrl, dPopToken, insertQuery);

    String dPopTokenIv =
        genDpopToken(encFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
    String insertQueryIv = genSparqlQuery('INSERT', '', ivValPred, ivValStr);
    String insertResponseIv =
        await runQuery(encFileUrl, dPopTokenIv, insertQueryIv);

    if (insertResponse == 'ok' && insertResponseIv == 'ok') {
      /// Get the list of locations of files that are encrypted
      var keyInfo = await fetchFile(encKeyFileLoc);
      EncProfile keyFile = EncProfile(keyInfo.toString());
      String encFileHash = keyFile.getEncFileHash();
      String encIvVal = keyFile.getEncIvVal();

      String fileListStr = '';

      /// New list of locations
      if (encFileHash.isEmpty) {
        List fileList = ['$filePath/$fileName'];
        fileListStr = jsonEncode(fileList);
      } else {
        String encFilePlaintext = decryptVal(encKey, encFileHash, encIvVal);
        List fileList = jsonDecode(encFilePlaintext);
        fileList.add('$filePath/$fileName');
        fileListStr = jsonEncode(fileList);
      }

      /// Update the list of encrypted file locations in the server
      if (fileListStr.isNotEmpty) {
        String encKeyFileUrl =
            webId.replaceAll('profile/card#me', encKeyFileLoc);
        List fileListEncRes = encryptVal(encKey, fileListStr);
        String fileListStrEnc = fileListEncRes[0];
        String fileListIv = fileListEncRes[1];

        // Update encrypted value
        String dPopToken =
            genDpopToken(encKeyFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');

        String updateQuery = genSparqlQuery(
            'UPDATE', '', encFilePred, fileListStrEnc,
            prevObject: encFileHash);

        String updateResponse =
            await runQuery(encKeyFileUrl, dPopToken, updateQuery);

        // Update iv value
        String dPopTokenIv =
            genDpopToken(encKeyFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');

        String updateQueryIv = genSparqlQuery(
            'UPDATE', '', ivValPred, fileListIv,
            prevObject: encIvVal);

        String updateResponseIv =
            await runQuery(encKeyFileUrl, dPopTokenIv, updateQueryIv);

        if (updateResponse != 'ok' || updateResponseIv != 'ok') {
          throw Exception('Failed to update encrypted file locations.');
        }
      }
    } else {
      throw Exception('Failed to encrypt the file.');
    }
  } else {
    throw Exception('Failed to delete the file! Try again in a while.');
  }
}