refactor: use OpenSSL for file e2ee

This commit is contained in:
Lukas Lihotzki 2021-03-25 14:05:34 +01:00
parent 761138a56d
commit d413f54f10
9 changed files with 76 additions and 7 deletions

View File

@ -20,7 +20,6 @@ import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart';
import '../famedlysdk.dart'; import '../famedlysdk.dart';
import 'database/database.dart' show DbRoomState, DbEvent; import 'database/database.dart' show DbRoomState, DbEvent;
@ -29,6 +28,7 @@ import 'utils/matrix_localizations.dart';
import 'utils/receipt.dart'; import 'utils/receipt.dart';
import 'utils/run_in_background.dart'; import 'utils/run_in_background.dart';
import 'utils/event_localizations.dart'; import 'utils/event_localizations.dart';
import 'utils/crypto/encrypted_file.dart';
abstract class RelationshipTypes { abstract class RelationshipTypes {
static const String reply = 'm.in_reply_to'; static const String reply = 'm.in_reply_to';

View File

@ -21,7 +21,6 @@ import 'dart:convert';
import 'package:famedlysdk/src/utils/space_child.dart'; import 'package:famedlysdk/src/utils/space_child.dart';
import 'package:html_unescape/html_unescape.dart'; import 'package:html_unescape/html_unescape.dart';
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart';
import '../famedlysdk.dart'; import '../famedlysdk.dart';
import 'client.dart'; import 'client.dart';
@ -29,6 +28,7 @@ import 'database/database.dart' show DbRoom;
import 'event.dart'; import 'event.dart';
import 'timeline.dart'; import 'timeline.dart';
import 'user.dart'; import 'user.dart';
import 'utils/crypto/encrypted_file.dart';
import 'utils/event_update.dart'; import 'utils/event_update.dart';
import 'utils/markdown.dart'; import 'utils/markdown.dart';
import 'utils/marked_unread.dart'; import 'utils/marked_unread.dart';

View File

@ -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<EncryptedFile> 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<Uint8List> 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);
}

View File

@ -63,3 +63,14 @@ final EVP_CIPHER_CTX_free = libcrypto.lookupFunction<
Pointer<NativeType> Function(Pointer<NativeType> ctx), Pointer<NativeType> Function(Pointer<NativeType> ctx),
Pointer<NativeType> Function(Pointer<NativeType> ctx) Pointer<NativeType> Function(Pointer<NativeType> ctx)
>('EVP_CIPHER_CTX_free'); >('EVP_CIPHER_CTX_free');
final EVP_Digest = libcrypto.lookupFunction<
IntPtr Function(Pointer<Uint8> data, IntPtr len, Pointer<Uint8> hash, Pointer<IntPtr> hsize, Pointer<NativeType> alg, Pointer<NativeType> engine),
int Function(Pointer<Uint8> data, int len, Pointer<Uint8> hash, Pointer<IntPtr> hsize, Pointer<NativeType> alg, Pointer<NativeType> engine)
>('EVP_Digest');
final EVP_MD_size = libcrypto.lookupFunction<
IntPtr Function(Pointer<NativeType> ctx),
int Function(Pointer<NativeType> ctx)
>('EVP_MD_size');

View File

@ -9,6 +9,8 @@ import 'subtle.dart' as subtle;
abstract class Hash { abstract class Hash {
Hash._(this.name); Hash._(this.name);
String name; String name;
Future<Uint8List> call(Uint8List input) async => Uint8List.view(await digest(name, input));
} }
final Hash sha1 = _Sha1(); final Hash sha1 = _Sha1();

View File

@ -7,6 +7,19 @@ import 'ffi.dart';
abstract class Hash { abstract class Hash {
Hash._(this.ptr); Hash._(this.ptr);
Pointer<NativeType> ptr; Pointer<NativeType> ptr;
Uint8List call(Uint8List data) {
final outSize = EVP_MD_size(ptr);
final mem = malloc.call<Uint8>(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(); final Hash sha1 = _Sha1();

View File

@ -75,3 +75,10 @@ external dynamic _deriveBits(dynamic algorithm, CryptoKey baseKey, int length);
Future<ByteBuffer> deriveBits(dynamic algorithm, CryptoKey baseKey, int length) { Future<ByteBuffer> deriveBits(dynamic algorithm, CryptoKey baseKey, int length) {
return promiseToFuture(_deriveBits(algorithm, baseKey, length)); return promiseToFuture(_deriveBits(algorithm, baseKey, length));
} }
@JS('crypto.subtle.digest')
external dynamic _digest(String algorithm, Uint8List data);
Future<ByteBuffer> digest(String algorithm, Uint8List data) {
return promiseToFuture(_digest(algorithm, data));
}

View File

@ -20,7 +20,7 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; import 'crypto/encrypted_file.dart';
import 'package:mime/mime.dart'; import 'package:mime/mime.dart';
import '../../famedlysdk.dart'; import '../../famedlysdk.dart';

View File

@ -18,10 +18,6 @@ dependencies:
crypto: ^3.0.0 crypto: ^3.0.0
base58check: ^2.0.0 base58check: ^2.0.0
olm: ^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 isolate: ^2.0.3
logger: ^1.0.0 logger: ^1.0.0
matrix_api_lite: ^0.2.4 matrix_api_lite: ^0.2.4