diff --git a/bin/_argon2.dart b/bin/_argon2.dart new file mode 100644 index 0000000..f49c070 --- /dev/null +++ b/bin/_argon2.dart @@ -0,0 +1,50 @@ +// ignore_for_file: non_constant_identifier_names + +//typedef HashStuff = Pointer Function(Pointer str); +import 'dart:ffi'; +import 'dart:io'; + +import 'package:ffi/ffi.dart'; +import 'package:kdbx/kdbx.dart'; + +// TODO: This should be somehow combined with the test variant +// which also loads the requierd dylib/so files. + +typedef Argon2HashNative = Pointer Function( + Pointer key, + IntPtr keyLen, + Pointer salt, + Uint64 saltlen, + Uint32 m_cost, // memory cost + Uint32 t_cost, // time cost (number iterations) + Uint32 parallelism, + IntPtr hashlen, + Uint8 type, + Uint32 version, +); +typedef Argon2Hash = Pointer Function( + Pointer key, + int keyLen, + Pointer salt, + int saltlen, + int m_cost, // memory cost + int t_cost, // time cost (number iterations) + int parallelism, + int hashlen, + int type, + int version, +); + +class Argon2Test extends Argon2Base { + Argon2Test() { + final argon2lib = Platform.isMacOS + ? DynamicLibrary.open('libargon2_ffi.dylib') + : DynamicLibrary.open('./libargon2_ffi.so'); + argon2hash = argon2lib + .lookup>('hp_argon2_hash') + .asFunction(); + } + + @override + Argon2Hash argon2hash; +} diff --git a/bin/kdbx.dart b/bin/kdbx.dart index 9811553..eb49717 100644 --- a/bin/kdbx.dart +++ b/bin/kdbx.dart @@ -11,6 +11,8 @@ import 'package:logging/logging.dart'; import 'package:logging_appenders/logging_appenders.dart'; import 'package:prompts/prompts.dart' as prompts; +import '_argon2.dart'; + final _logger = Logger('kdbx'); void main(List arguments) { @@ -63,6 +65,12 @@ abstract class KdbxFileCommand extends Command { help: 'Input kdbx file', valueHelp: 'foo.kdbx', ); + argParser.addOption( + 'password', + abbr: 'p', + help: 'password', + valueHelp: 'asdf', + ); } @override @@ -72,9 +80,10 @@ abstract class KdbxFileCommand extends Command { usageException('Required argument: --input'); } final bytes = await File(inputFile).readAsBytes(); - final password = prompts.get('Password for $inputFile', - conceal: true, validate: (str) => str.isNotEmpty); - final file = await KdbxFormat(null) + final password = argResults['password'] as String ?? + prompts.get('Password for $inputFile', + conceal: true, validate: (str) => str.isNotEmpty); + final file = await KdbxFormat(Argon2Test()) .read(bytes, Credentials(ProtectedValue.fromString(password))); return runWithFile(file); } diff --git a/lib/src/kdbx_format.dart b/lib/src/kdbx_format.dart index a5c70f9..ff0d1af 100644 --- a/lib/src/kdbx_format.dart +++ b/lib/src/kdbx_format.dart @@ -632,6 +632,7 @@ class KdbxFormat { Uint8List _decryptContentV4( KdbxHeader header, Uint8List cipherKey, Uint8List encryptedPayload) { final encryptionIv = header.fields[HeaderFields.EncryptionIV].bytes; + final decryptCipher = CBCBlockCipher(AESFastEngine()); decryptCipher.init( false, ParametersWithIV(KeyParameter(cipherKey), encryptionIv));