Browse Source

basic dart2js / dart web support.

coverage
Herbert Poul 4 years ago
parent
commit
e24ff0e19a
  1. 27
      example/pubspec.lock
  2. 3
      lib/src/crypto/key_encrypter_kdf.dart
  3. 35
      lib/src/internal/byte_utils.dart
  4. 25
      lib/src/kdbx_format.dart
  5. 1
      pubspec.yaml

27
example/pubspec.lock

@ -1,13 +1,20 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
argon2_ffi_base: argon2_ffi_base:
dependency: transitive dependency: transitive
description: description:
name: argon2_ffi_base name: argon2_ffi_base
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.1" version: "0.1.4+2"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -15,13 +22,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.2" version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -85,13 +85,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.3" version: "0.1.3"
ffi_helper:
dependency: transitive
description:
name: ffi_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
intl: intl:
dependency: transitive dependency: transitive
description: description:
@ -119,14 +112,14 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.3.1" version: "0.4.0+1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
name: logging name: logging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.11.3+2" version: "0.11.4"
logging_appenders: logging_appenders:
dependency: transitive dependency: transitive
description: description:

3
lib/src/crypto/key_encrypter_kdf.dart

@ -121,6 +121,9 @@ class KeyEncrypterKdf {
} }
static Future<Uint8List> encryptAesAsync(EncryptAesArgs args) async { static Future<Uint8List> encryptAesAsync(EncryptAesArgs args) async {
if (KdbxFormat.dartWebWorkaround) {
return _encryptAesSync(args);
}
final runner = await IsolateRunner.spawn(); final runner = await IsolateRunner.spawn();
final s = Stopwatch()..start(); final s = Stopwatch()..start();
try { try {

35
lib/src/internal/byte_utils.dart

@ -35,11 +35,9 @@ class ByteUtils {
list?.map((val) => toHex(val))?.join(' ') ?? '(null)'; list?.map((val) => toHex(val))?.join(' ') ?? '(null)';
} }
const dartWebWorkaround = true;
class ReaderHelper { class ReaderHelper {
factory ReaderHelper(Uint8List byteData) => KdbxFormat.dartWebWorkaround factory ReaderHelper(Uint8List byteData) => KdbxFormat.dartWebWorkaround
? ReaderHelper(byteData) ? ReaderHelperDartWeb(byteData)
: ReaderHelper._(byteData); : ReaderHelper._(byteData);
ReaderHelper._(this.byteData) : lengthInBytes = byteData.lengthInBytes; ReaderHelper._(this.byteData) : lengthInBytes = byteData.lengthInBytes;
@ -85,24 +83,10 @@ class ReaderHelper {
int readUint8() => _nextByteBuffer(1).getUint8(0); int readUint8() => _nextByteBuffer(1).getUint8(0);
int readUint16() => _nextByteBuffer(2).getUint16(0, Endian.little); int readUint16() => _nextByteBuffer(2).getUint16(0, Endian.little);
int readUint32() => _nextByteBuffer(4).getUint32(0, Endian.little); int readUint32() => _nextByteBuffer(4).getUint32(0, Endian.little);
int readUint64() { int readUint64() => _nextByteBuffer(8).getUint64(0, Endian.little);
if (!dartWebWorkaround) {
return _nextByteBuffer(8).getUint64(0, Endian.little);
} else {
final lo = readUint32();
final hi = readUint32();
return hi << 32 + lo;
}
}
int readInt32() => _nextByteBuffer(4).getInt32(0, Endian.little); int readInt32() => _nextByteBuffer(4).getInt32(0, Endian.little);
int readInt64() { int readInt64() => _nextByteBuffer(8).getInt64(0, Endian.little);
if (!dartWebWorkaround) {
return _nextByteBuffer(8).getInt64(0, Endian.little);
} else {
return readUint64();
}
}
Uint8List readBytes(int size) => _nextBytes(size); Uint8List readBytes(int size) => _nextBytes(size);
@ -119,6 +103,19 @@ class ReaderHelper {
class ReaderHelperDartWeb extends ReaderHelper { class ReaderHelperDartWeb extends ReaderHelper {
ReaderHelperDartWeb(Uint8List byteData) : super._(byteData); 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); typedef LengthWriter = void Function(int length);

25
lib/src/kdbx_format.dart

@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:archive/archive.dart';
import 'package:argon2_ffi_base/argon2_ffi_base.dart'; import 'package:argon2_ffi_base/argon2_ffi_base.dart';
import 'package:convert/convert.dart' as convert; import 'package:convert/convert.dart' as convert;
import 'package:crypto/crypto.dart' as crypto; import 'package:crypto/crypto.dart' as crypto;
@ -212,7 +213,7 @@ class KdbxBody extends KdbxNode {
final xml = generateXml(saltGenerator); final xml = generateXml(saltGenerator);
final xmlBytes = utf8.encode(xml.toXmlString()); final xmlBytes = utf8.encode(xml.toXmlString());
final compressedBytes = (kdbxFile.header.compression == Compression.gzip final compressedBytes = (kdbxFile.header.compression == Compression.gzip
? GZipCodec().encode(xmlBytes) ? KdbxFormat._gzipEncode(xmlBytes as Uint8List)
: xmlBytes) as Uint8List; : xmlBytes) as Uint8List;
final encrypted = await _encryptV3(kdbxFile, compressedBytes); final encrypted = await _encryptV3(kdbxFile, compressedBytes);
@ -227,8 +228,8 @@ class KdbxBody extends KdbxNode {
kdbxFile.header.writeInnerHeader(bodyWriter); kdbxFile.header.writeInnerHeader(bodyWriter);
bodyWriter.writeBytes(utf8.encode(xml.toXmlString()) as Uint8List); bodyWriter.writeBytes(utf8.encode(xml.toXmlString()) as Uint8List);
final compressedBytes = (kdbxFile.header.compression == Compression.gzip final compressedBytes = (kdbxFile.header.compression == Compression.gzip
? GZipCodec().encode(bodyWriter.output.toBytes()) ? KdbxFormat._gzipEncode(bodyWriter.output.toBytes())
: bodyWriter.output.toBytes()) as Uint8List; : bodyWriter.output.toBytes());
final encrypted = _encryptV4( final encrypted = _encryptV4(
kdbxFile, kdbxFile,
compressedBytes, compressedBytes,
@ -409,7 +410,7 @@ class KdbxFormat {
_logger.finer('compression: ${header.compression}'); _logger.finer('compression: ${header.compression}');
final ctx = KdbxReadWriteContext(binaries: [], header: header); final ctx = KdbxReadWriteContext(binaries: [], header: header);
if (header.compression == Compression.gzip) { if (header.compression == Compression.gzip) {
final xml = GZipCodec().decode(blocks); final xml = KdbxFormat._gzipDecode(blocks);
final string = utf8.decode(xml); final string = utf8.decode(xml);
return KdbxFile( return KdbxFile(
ctx, this, credentials, header, _loadXml(ctx, header, string)); ctx, this, credentials, header, _loadXml(ctx, header, string));
@ -447,7 +448,7 @@ class KdbxFormat {
final decrypted = decrypt(header, bodyContent, keys.cipherKey); final decrypted = decrypt(header, bodyContent, keys.cipherKey);
_logger.finer('compression: ${header.compression}'); _logger.finer('compression: ${header.compression}');
if (header.compression == Compression.gzip) { if (header.compression == Compression.gzip) {
final content = GZipCodec().decode(decrypted) as Uint8List; final content = KdbxFormat._gzipDecode(decrypted);
final contentReader = ReaderHelper(content); final contentReader = ReaderHelper(content);
final innerHeader = KdbxHeader.readInnerHeaderFields(contentReader, 4); final innerHeader = KdbxHeader.readInnerHeaderFields(contentReader, 4);
@ -715,4 +716,18 @@ class KdbxFormat {
return AesHelper.processBlocks( return AesHelper.processBlocks(
encryptCipher, AesHelper.pad(payload, encryptCipher.blockSize)); 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;
}
} }

1
pubspec.yaml

@ -22,6 +22,7 @@ dependencies:
isolate: '>=2.0.3 <3.0.0' isolate: '>=2.0.3 <3.0.0'
path: '>=1.6.0 <2.0.0' path: '>=1.6.0 <2.0.0'
quiver: '>=2.1.0 <3.0.0' quiver: '>=2.1.0 <3.0.0'
archive: '>=2.0.13 <3.0.0'
collection: '>=1.14.0 <2.0.0' collection: '>=1.14.0 <2.0.0'

Loading…
Cancel
Save