diff --git a/bin/kdbx.dart b/bin/kdbx.dart index 2efc43e..971ce70 100644 --- a/bin/kdbx.dart +++ b/bin/kdbx.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:io'; -import 'dart:typed_data'; import 'package:args/args.dart'; import 'package:args/command_runner.dart'; @@ -72,7 +71,7 @@ abstract class KdbxFileCommand extends Command { if (inputFile == null) { usageException('Required argument: --input'); } - final bytes = await File(inputFile).readAsBytes() as Uint8List; + final bytes = await File(inputFile).readAsBytes(); final password = prompts.get('Password for $inputFile', conceal: true, validate: (str) => str.isNotEmpty); final file = KdbxFormat.read( diff --git a/example/pubspec.lock b/example/pubspec.lock index 6e5c40c..22a1bc3 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -82,7 +82,7 @@ packages: path: ".." relative: true source: path - version: "0.1.0" + version: "0.2.1" logging: dependency: transitive description: @@ -103,7 +103,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.7" + version: "1.1.8" path: dependency: transitive description: diff --git a/lib/kdbx.dart b/lib/kdbx.dart index d103af3..b2c5458 100644 --- a/lib/kdbx.dart +++ b/lib/kdbx.dart @@ -1,7 +1,8 @@ /// dart library for reading keepass file format (kdbx). library kdbx; -export 'src/crypto/protected_value.dart' show ProtectedValue, StringValue, PlainValue; +export 'src/crypto/protected_value.dart' + show ProtectedValue, StringValue, PlainValue; export 'src/kdbx_consts.dart'; export 'src/kdbx_entry.dart'; export 'src/kdbx_format.dart'; diff --git a/lib/src/internal/async_utils.dart b/lib/src/internal/async_utils.dart index 3ee99fc..a6d58d8 100644 --- a/lib/src/internal/async_utils.dart +++ b/lib/src/internal/async_utils.dart @@ -3,10 +3,12 @@ import 'dart:async'; /// Base class which can be used as a mixin directly, but you have to call `cancelSubscriptions`. /// If used inside a [State], use [StreamSubscriberMixin]. mixin StreamSubscriberBase { - final List> _subscriptions = >[]; + final List> _subscriptions = + >[]; /// Listens to a stream and saves it to the list of subscriptions. - void listen(Stream stream, void onData(dynamic data), {Function onError}) { + void listen(Stream stream, void onData(dynamic data), + {Function onError}) { if (stream != null) { _subscriptions.add(stream.listen(onData, onError: onError)); } diff --git a/lib/src/internal/crypto_utils.dart b/lib/src/internal/crypto_utils.dart index 8733d4a..e73c91b 100644 --- a/lib/src/internal/crypto_utils.dart +++ b/lib/src/internal/crypto_utils.dart @@ -1,5 +1,3 @@ - - import 'dart:typed_data'; import 'package:pointycastle/export.dart'; @@ -14,25 +12,29 @@ class AesHelper { static const ITERATION_COUNT = 1000; static Uint8List deriveKey( - Uint8List password, { - Uint8List salt, - int iterationCount = ITERATION_COUNT, - int derivedKeyLength = KEY_SIZE, - }) { - final Pbkdf2Parameters params = Pbkdf2Parameters(salt, iterationCount, derivedKeyLength); - final KeyDerivator keyDerivator = PBKDF2KeyDerivator(HMac(SHA256Digest(), 16)); + Uint8List password, { + Uint8List salt, + int iterationCount = ITERATION_COUNT, + int derivedKeyLength = KEY_SIZE, + }) { + final Pbkdf2Parameters params = + Pbkdf2Parameters(salt, iterationCount, derivedKeyLength); + final KeyDerivator keyDerivator = + PBKDF2KeyDerivator(HMac(SHA256Digest(), 16)); keyDerivator.init(params); return keyDerivator.process(password); } - static String decrypt(Uint8List derivedKey, Uint8List cipherIvBytes, {String mode = CBC_MODE}) { + static String decrypt(Uint8List derivedKey, Uint8List cipherIvBytes, + {String mode = CBC_MODE}) { // Uint8List derivedKey = deriveKey(password); final KeyParameter keyParam = KeyParameter(derivedKey); final BlockCipher aes = AESFastEngine(); // Uint8List cipherIvBytes = base64.decode(ciphertext); - final Uint8List iv = Uint8List(aes.blockSize)..setRange(0, aes.blockSize, cipherIvBytes); + final Uint8List iv = Uint8List(aes.blockSize) + ..setRange(0, aes.blockSize, cipherIvBytes); BlockCipher cipher; final ParametersWithIV params = ParametersWithIV(keyParam, iv); @@ -50,7 +52,8 @@ class AesHelper { cipher.init(false, params); final int cipherLen = cipherIvBytes.length - aes.blockSize; - final Uint8List cipherBytes = Uint8List(cipherLen)..setRange(0, cipherLen, cipherIvBytes, aes.blockSize); + final Uint8List cipherBytes = Uint8List(cipherLen) + ..setRange(0, cipherLen, cipherIvBytes, aes.blockSize); final Uint8List paddedText = processBlocks(cipher, cipherBytes); final Uint8List textBytes = unpad(paddedText); diff --git a/lib/src/kdbx_entry.dart b/lib/src/kdbx_entry.dart index bff1ab8..7a430f6 100644 --- a/lib/src/kdbx_entry.dart +++ b/lib/src/kdbx_entry.dart @@ -51,7 +51,7 @@ class KdbxEntry extends KdbxObject { } final bool isHistoryEntry; - + List _history; List get history => _history ??= (() { @@ -134,7 +134,7 @@ class KdbxEntry extends KdbxObject { _strings[key] = value; } } - + void renameKey(KdbxKey oldKey, KdbxKey newKey) { final value = _strings[oldKey]; removeString(oldKey); diff --git a/lib/src/kdbx_format.dart b/lib/src/kdbx_format.dart index d5df660..b9cea35 100644 --- a/lib/src/kdbx_format.dart +++ b/lib/src/kdbx_format.dart @@ -30,8 +30,6 @@ abstract class Credentials { keyFile: keyFile == null ? null : KeyFileCredentials(keyFile), ); - Credentials._(); - factory Credentials.fromHash(Uint8List hash) => HashCredentials(hash); Uint8List getHash(); @@ -42,6 +40,7 @@ class KeyFileComposite implements Credentials { PasswordCredentials password; KeyFileCredentials keyFile; + @override Uint8List getHash() { final buffer = [...?password?.getBinary(), ...?keyFile?.getBinary()]; return crypto.sha256.convert(buffer).bytes as Uint8List; diff --git a/lib/src/kdbx_times.dart b/lib/src/kdbx_times.dart index 598e118..80f8d8a 100644 --- a/lib/src/kdbx_times.dart +++ b/lib/src/kdbx_times.dart @@ -1,5 +1,3 @@ - - import 'package:clock/clock.dart'; import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_xml.dart'; @@ -19,12 +17,14 @@ class KdbxTimes extends KdbxNode { KdbxTimes.read(XmlElement node) : super.read(node); DateTimeUtcNode get creationTime => DateTimeUtcNode(this, 'CreationTime'); - DateTimeUtcNode get lastModificationTime => DateTimeUtcNode(this, 'CreationTime'); + DateTimeUtcNode get lastModificationTime => + DateTimeUtcNode(this, 'CreationTime'); DateTimeUtcNode get lastAccessTime => DateTimeUtcNode(this, 'CreationTime'); DateTimeUtcNode get expiryTime => DateTimeUtcNode(this, 'CreationTime'); BooleanNode get expires => BooleanNode(this, 'Expires'); IntNode get usageCount => IntNode(this, 'Usagecount'); - DateTimeUtcNode get locationChanged => DateTimeUtcNode(this, 'LocationChanged'); + DateTimeUtcNode get locationChanged => + DateTimeUtcNode(this, 'LocationChanged'); void accessedNow() { lastAccessTime.set(clock.now().toUtc());