From d413f54f102b5420f2e3d67f053f400aa227e68c Mon Sep 17 00:00:00 2001 From: Lukas Lihotzki Date: Thu, 25 Mar 2021 14:05:34 +0100 Subject: [PATCH] refactor: use OpenSSL for file e2ee --- lib/src/event.dart | 2 +- lib/src/room.dart | 2 +- lib/src/utils/crypto/encrypted_file.dart | 40 ++++++++++++++++++++++++ lib/src/utils/crypto/ffi.dart | 11 +++++++ lib/src/utils/crypto/js.dart | 2 ++ lib/src/utils/crypto/native.dart | 13 ++++++++ lib/src/utils/crypto/subtle.dart | 7 +++++ lib/src/utils/matrix_file.dart | 2 +- pubspec.yaml | 4 --- 9 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 lib/src/utils/crypto/encrypted_file.dart diff --git a/lib/src/event.dart b/lib/src/event.dart index a8fd73be..413f90a3 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -20,7 +20,6 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:http/http.dart' as http; -import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; import '../famedlysdk.dart'; import 'database/database.dart' show DbRoomState, DbEvent; @@ -29,6 +28,7 @@ import 'utils/matrix_localizations.dart'; import 'utils/receipt.dart'; import 'utils/run_in_background.dart'; import 'utils/event_localizations.dart'; +import 'utils/crypto/encrypted_file.dart'; abstract class RelationshipTypes { static const String reply = 'm.in_reply_to'; diff --git a/lib/src/room.dart b/lib/src/room.dart index 2ad1585e..eb18b95e 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -21,7 +21,6 @@ import 'dart:convert'; import 'package:famedlysdk/src/utils/space_child.dart'; import 'package:html_unescape/html_unescape.dart'; -import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; import '../famedlysdk.dart'; import 'client.dart'; @@ -29,6 +28,7 @@ import 'database/database.dart' show DbRoom; import 'event.dart'; import 'timeline.dart'; import 'user.dart'; +import 'utils/crypto/encrypted_file.dart'; import 'utils/event_update.dart'; import 'utils/markdown.dart'; import 'utils/marked_unread.dart'; diff --git a/lib/src/utils/crypto/encrypted_file.dart b/lib/src/utils/crypto/encrypted_file.dart new file mode 100644 index 00000000..9f48a00a --- /dev/null +++ b/lib/src/utils/crypto/encrypted_file.dart @@ -0,0 +1,40 @@ +import 'dart:typed_data'; +import 'dart:convert'; + +import 'crypto.dart'; + +class EncryptedFile { + EncryptedFile({ + this.data, + this.k, + this.iv, + this.sha256, + }); + Uint8List data; + String k; + String iv; + String sha256; +} + +Future encryptFile(Uint8List input) async { + final key = secureRandomBytes(32); + final iv = secureRandomBytes(16); + final data = await aesCtr.encrypt(input, key, iv); + final hash = await sha256(data); + return EncryptedFile( + data: data, + k: base64Url.encode(key).replaceAll('=', ''), + iv: base64.encode(iv).replaceAll('=', ''), + sha256: base64.encode(hash).replaceAll('=', ''), + ); +} + +Future decryptFile(EncryptedFile input) async { + if (base64.encode(await sha256(input.data)) != base64.normalize(input.sha256)) { + return null; + } + + final key = base64.decode(base64.normalize(input.k)); + final iv = base64.decode(base64.normalize(input.iv)); + return await aesCtr.encrypt(input.data, key, iv); +} diff --git a/lib/src/utils/crypto/ffi.dart b/lib/src/utils/crypto/ffi.dart index 1a6aec8d..a04d9b9f 100644 --- a/lib/src/utils/crypto/ffi.dart +++ b/lib/src/utils/crypto/ffi.dart @@ -63,3 +63,14 @@ final EVP_CIPHER_CTX_free = libcrypto.lookupFunction< Pointer Function(Pointer ctx), Pointer Function(Pointer ctx) >('EVP_CIPHER_CTX_free'); + +final EVP_Digest = libcrypto.lookupFunction< + IntPtr Function(Pointer data, IntPtr len, Pointer hash, Pointer hsize, Pointer alg, Pointer engine), + int Function(Pointer data, int len, Pointer hash, Pointer hsize, Pointer alg, Pointer engine) +>('EVP_Digest'); + +final EVP_MD_size = libcrypto.lookupFunction< + IntPtr Function(Pointer ctx), + int Function(Pointer ctx) +>('EVP_MD_size'); + diff --git a/lib/src/utils/crypto/js.dart b/lib/src/utils/crypto/js.dart index 39606bc7..798b4064 100644 --- a/lib/src/utils/crypto/js.dart +++ b/lib/src/utils/crypto/js.dart @@ -9,6 +9,8 @@ import 'subtle.dart' as subtle; abstract class Hash { Hash._(this.name); String name; + + Future call(Uint8List input) async => Uint8List.view(await digest(name, input)); } final Hash sha1 = _Sha1(); diff --git a/lib/src/utils/crypto/native.dart b/lib/src/utils/crypto/native.dart index 66c9af0f..6406af23 100644 --- a/lib/src/utils/crypto/native.dart +++ b/lib/src/utils/crypto/native.dart @@ -7,6 +7,19 @@ import 'ffi.dart'; abstract class Hash { Hash._(this.ptr); Pointer ptr; + + Uint8List call(Uint8List data) { + final outSize = EVP_MD_size(ptr); + final mem = malloc.call(outSize + data.length); + final dataMem = mem.elementAt(outSize); + try { + dataMem.asTypedList(data.length).setAll(0, data); + EVP_Digest(dataMem, data.length, mem, nullptr, ptr, nullptr); + return Uint8List.fromList(mem.asTypedList(outSize)); + } finally { + malloc.free(mem); + } + } } final Hash sha1 = _Sha1(); diff --git a/lib/src/utils/crypto/subtle.dart b/lib/src/utils/crypto/subtle.dart index d5b84b24..d2427ed3 100644 --- a/lib/src/utils/crypto/subtle.dart +++ b/lib/src/utils/crypto/subtle.dart @@ -75,3 +75,10 @@ external dynamic _deriveBits(dynamic algorithm, CryptoKey baseKey, int length); Future deriveBits(dynamic algorithm, CryptoKey baseKey, int length) { return promiseToFuture(_deriveBits(algorithm, baseKey, length)); } + +@JS('crypto.subtle.digest') +external dynamic _digest(String algorithm, Uint8List data); + +Future digest(String algorithm, Uint8List data) { + return promiseToFuture(_digest(algorithm, data)); +} diff --git a/lib/src/utils/matrix_file.dart b/lib/src/utils/matrix_file.dart index cc6cb6c7..fb88ad07 100644 --- a/lib/src/utils/matrix_file.dart +++ b/lib/src/utils/matrix_file.dart @@ -20,7 +20,7 @@ import 'dart:typed_data'; -import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; +import 'crypto/encrypted_file.dart'; import 'package:mime/mime.dart'; import '../../famedlysdk.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 4d6d081a..2198fe15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,10 +18,6 @@ dependencies: crypto: ^3.0.0 base58check: ^2.0.0 olm: ^2.0.0 - matrix_file_e2ee: - git: - url: https://gitlab.com/famedly/libraries/matrix_file_e2ee.git - ref: nullsafety isolate: ^2.0.3 logger: ^1.0.0 matrix_api_lite: ^0.2.4