refactor: use OpenSSL for file e2ee
This commit is contained in:
parent
761138a56d
commit
d413f54f10
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue