From e24ff0e19ada1fa2fd256839307cae14b01ec8b8 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Tue, 4 Aug 2020 00:32:39 +0200 Subject: [PATCH] basic dart2js / dart web support. --- example/pubspec.lock | 27 ++++++++------------- lib/src/crypto/key_encrypter_kdf.dart | 3 +++ lib/src/internal/byte_utils.dart | 35 ++++++++++++--------------- lib/src/kdbx_format.dart | 25 +++++++++++++++---- pubspec.yaml | 1 + 5 files changed, 50 insertions(+), 41 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 31a1933..62dc4bb 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,13 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" argon2_ffi_base: dependency: transitive description: name: argon2_ffi_base url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "0.1.4+2" args: dependency: transitive description: @@ -15,13 +22,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.2" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" charcode: dependency: transitive description: @@ -85,13 +85,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" - ffi_helper: - dependency: transitive - description: - name: ffi_helper - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" intl: dependency: transitive description: @@ -119,14 +112,14 @@ packages: path: ".." relative: true source: path - version: "0.3.1" + version: "0.4.0+1" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+2" + version: "0.11.4" logging_appenders: dependency: transitive description: diff --git a/lib/src/crypto/key_encrypter_kdf.dart b/lib/src/crypto/key_encrypter_kdf.dart index b529d33..489e1d8 100644 --- a/lib/src/crypto/key_encrypter_kdf.dart +++ b/lib/src/crypto/key_encrypter_kdf.dart @@ -121,6 +121,9 @@ class KeyEncrypterKdf { } static Future encryptAesAsync(EncryptAesArgs args) async { + if (KdbxFormat.dartWebWorkaround) { + return _encryptAesSync(args); + } final runner = await IsolateRunner.spawn(); final s = Stopwatch()..start(); try { diff --git a/lib/src/internal/byte_utils.dart b/lib/src/internal/byte_utils.dart index 2517872..0e25c4d 100644 --- a/lib/src/internal/byte_utils.dart +++ b/lib/src/internal/byte_utils.dart @@ -35,11 +35,9 @@ class ByteUtils { list?.map((val) => toHex(val))?.join(' ') ?? '(null)'; } -const dartWebWorkaround = true; - class ReaderHelper { factory ReaderHelper(Uint8List byteData) => KdbxFormat.dartWebWorkaround - ? ReaderHelper(byteData) + ? ReaderHelperDartWeb(byteData) : ReaderHelper._(byteData); ReaderHelper._(this.byteData) : lengthInBytes = byteData.lengthInBytes; @@ -85,24 +83,10 @@ class ReaderHelper { int readUint8() => _nextByteBuffer(1).getUint8(0); int readUint16() => _nextByteBuffer(2).getUint16(0, Endian.little); int readUint32() => _nextByteBuffer(4).getUint32(0, Endian.little); - int readUint64() { - if (!dartWebWorkaround) { - return _nextByteBuffer(8).getUint64(0, Endian.little); - } else { - final lo = readUint32(); - final hi = readUint32(); - return hi << 32 + lo; - } - } + int readUint64() => _nextByteBuffer(8).getUint64(0, Endian.little); int readInt32() => _nextByteBuffer(4).getInt32(0, Endian.little); - int readInt64() { - if (!dartWebWorkaround) { - return _nextByteBuffer(8).getInt64(0, Endian.little); - } else { - return readUint64(); - } - } + int readInt64() => _nextByteBuffer(8).getInt64(0, Endian.little); Uint8List readBytes(int size) => _nextBytes(size); @@ -119,6 +103,19 @@ class ReaderHelper { class ReaderHelperDartWeb extends ReaderHelper { ReaderHelperDartWeb(Uint8List byteData) : super._(byteData); + + @override + int readUint64() { + final lo = readUint32(); + final hi = readUint32(); + print('lo: $lo / hi: $hi ---- '); + return (hi << 32) + lo; + } + + @override + int readInt64() { + return readUint64(); + } } typedef LengthWriter = void Function(int length); diff --git a/lib/src/kdbx_format.dart b/lib/src/kdbx_format.dart index acac4e2..b9fa425 100644 --- a/lib/src/kdbx_format.dart +++ b/lib/src/kdbx_format.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:archive/archive.dart'; import 'package:argon2_ffi_base/argon2_ffi_base.dart'; import 'package:convert/convert.dart' as convert; import 'package:crypto/crypto.dart' as crypto; @@ -212,7 +213,7 @@ class KdbxBody extends KdbxNode { final xml = generateXml(saltGenerator); final xmlBytes = utf8.encode(xml.toXmlString()); final compressedBytes = (kdbxFile.header.compression == Compression.gzip - ? GZipCodec().encode(xmlBytes) + ? KdbxFormat._gzipEncode(xmlBytes as Uint8List) : xmlBytes) as Uint8List; final encrypted = await _encryptV3(kdbxFile, compressedBytes); @@ -227,8 +228,8 @@ class KdbxBody extends KdbxNode { kdbxFile.header.writeInnerHeader(bodyWriter); bodyWriter.writeBytes(utf8.encode(xml.toXmlString()) as Uint8List); final compressedBytes = (kdbxFile.header.compression == Compression.gzip - ? GZipCodec().encode(bodyWriter.output.toBytes()) - : bodyWriter.output.toBytes()) as Uint8List; + ? KdbxFormat._gzipEncode(bodyWriter.output.toBytes()) + : bodyWriter.output.toBytes()); final encrypted = _encryptV4( kdbxFile, compressedBytes, @@ -409,7 +410,7 @@ class KdbxFormat { _logger.finer('compression: ${header.compression}'); final ctx = KdbxReadWriteContext(binaries: [], header: header); if (header.compression == Compression.gzip) { - final xml = GZipCodec().decode(blocks); + final xml = KdbxFormat._gzipDecode(blocks); final string = utf8.decode(xml); return KdbxFile( ctx, this, credentials, header, _loadXml(ctx, header, string)); @@ -447,7 +448,7 @@ class KdbxFormat { final decrypted = decrypt(header, bodyContent, keys.cipherKey); _logger.finer('compression: ${header.compression}'); if (header.compression == Compression.gzip) { - final content = GZipCodec().decode(decrypted) as Uint8List; + final content = KdbxFormat._gzipDecode(decrypted); final contentReader = ReaderHelper(content); final innerHeader = KdbxHeader.readInnerHeaderFields(contentReader, 4); @@ -715,4 +716,18 @@ class KdbxFormat { return AesHelper.processBlocks( encryptCipher, AesHelper.pad(payload, encryptCipher.blockSize)); } + + static Uint8List _gzipEncode(Uint8List bytes) { + if (dartWebWorkaround) { + return GZipEncoder().encode(bytes) as Uint8List; + } + return GZipCodec().encode(bytes) as Uint8List; + } + + static Uint8List _gzipDecode(Uint8List bytes) { + if (dartWebWorkaround) { + return GZipDecoder().decodeBytes(bytes) as Uint8List; + } + return GZipCodec().decode(bytes) as Uint8List; + } } diff --git a/pubspec.yaml b/pubspec.yaml index f3c6da2..ba50cdd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: isolate: '>=2.0.3 <3.0.0' path: '>=1.6.0 <2.0.0' quiver: '>=2.1.0 <3.0.0' + archive: '>=2.0.13 <3.0.0' collection: '>=1.14.0 <2.0.0'