Browse Source

implemented test for reading and writing, fixed kdbx 4 binaries writing.

remove-cryptography-dependency
Herbert Poul 5 years ago
parent
commit
80a84e41aa
  1. 1
      .idea/dictionaries/herbert.xml
  2. 21
      lib/src/kdbx_header.dart
  3. 9
      test/internal/test_utils.dart
  4. 44
      test/kdbx_binaries_test.dart

1
.idea/dictionaries/herbert.xml

@ -6,6 +6,7 @@
<w>encrypter</w> <w>encrypter</w>
<w>hmac</w> <w>hmac</w>
<w>kdbx</w> <w>kdbx</w>
<w>keepass</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>

21
lib/src/kdbx_header.dart

@ -227,18 +227,26 @@ class KdbxHeader {
_validateInner(); _validateInner();
for (final field in InnerHeaderFields.values for (final field in InnerHeaderFields.values
.where((f) => f != InnerHeaderFields.EndOfHeader)) { .where((f) => f != InnerHeaderFields.EndOfHeader)) {
_writeInnerField(writer, field); _writeInnerFieldIfExist(writer, field);
}
// write attachments
for (final binary in innerHeader.binaries) {
_writeInnerField(writer, binary);
} }
// TODO write attachments
_setInnerHeaderField(InnerHeaderFields.EndOfHeader, Uint8List(0)); _setInnerHeaderField(InnerHeaderFields.EndOfHeader, Uint8List(0));
_writeInnerField(writer, InnerHeaderFields.EndOfHeader); _writeInnerFieldIfExist(writer, InnerHeaderFields.EndOfHeader);
} }
void _writeInnerField(WriterHelper writer, InnerHeaderFields field) { void _writeInnerFieldIfExist(WriterHelper writer, InnerHeaderFields field) {
final value = innerHeader.fields[field]; final value = innerHeader.fields[field];
if (value == null) { if (value == null) {
return; return;
} }
_writeInnerField(writer, value);
}
void _writeInnerField(WriterHelper writer, InnerHeaderField value) {
final field = value.field;
_logger.finer( _logger.finer(
'Writing header $field (${field.index}) (${value.bytes.lengthInBytes})'); 'Writing header $field (${field.index}) (${value.bytes.lengthInBytes})');
writer.writeUint8(field.index); writer.writeUint8(field.index);
@ -438,6 +446,11 @@ class KdbxCorruptedFileException implements KdbxException {
KdbxCorruptedFileException([this.message]); KdbxCorruptedFileException([this.message]);
final String message; final String message;
@override
String toString() {
return 'KdbxCorruptedFileException{message: $message}';
}
} }
class KdbxUnsupportedException implements KdbxException { class KdbxUnsupportedException implements KdbxException {

9
test/internal/test_utils.dart

@ -1,6 +1,7 @@
//typedef HashStuff = Pointer<Utf8> Function(Pointer<Utf8> str); //typedef HashStuff = Pointer<Utf8> Function(Pointer<Utf8> str);
import 'dart:ffi'; import 'dart:ffi';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
@ -55,4 +56,12 @@ class TestUtil {
data, Credentials(ProtectedValue.fromString(password))); data, Credentials(ProtectedValue.fromString(password)));
return file; return file;
} }
static Future<KdbxFile> readKdbxFileBytes(Uint8List data,
{String password = 'asdf'}) async {
final kdbxFormat = KdbxFormat(Argon2Test());
final file = await kdbxFormat.read(
data, Credentials(ProtectedValue.fromString(password)));
return file;
}
} }

44
test/kdbx_binaries_test.dart

@ -8,14 +8,20 @@ import 'package:test/test.dart';
import 'internal/test_utils.dart'; import 'internal/test_utils.dart';
void expectBinary(KdbxEntry entry, String key, dynamic matcher) {
final binaries = entry.binaryEntries;
expect(binaries, hasLength(1));
final binary = binaries.first;
expect(binary.key.key, key);
expect(binary.value.value, matcher);
}
void main() { void main() {
Logger.root.level = Level.ALL; Logger.root.level = Level.ALL;
PrintAppender().attachToLogger(Logger.root); PrintAppender().attachToLogger(Logger.root);
group('kdbx3 attachment', () { group('kdbx3 attachment', () {
test('read binary', () async { void expectKeepass2binariesContents(KdbxEntry entry) {
final file = await TestUtil.readKdbxFile('test/keepass2binaries.kdbx');
final entry = file.body.rootGroup.entries.first;
final binaries = entry.binaryEntries; final binaries = entry.binaryEntries;
expect(binaries, hasLength(3)); expect(binaries, hasLength(3));
for (final binary in binaries) { for (final binary in binaries) {
@ -33,19 +39,26 @@ void main() {
fail('invalid key. ${binary.key}'); fail('invalid key. ${binary.key}');
} }
} }
}
test('read binary', () async {
final file = await TestUtil.readKdbxFile('test/keepass2binaries.kdbx');
final entry = file.body.rootGroup.entries.first;
expectKeepass2binariesContents(entry);
});
test('read write read', () async {
final fileRead =
await TestUtil.readKdbxFile('test/keepass2binaries.kdbx');
final saved = await fileRead.save();
final file = await TestUtil.readKdbxFileBytes(saved);
final entry = file.body.rootGroup.entries.first;
expectKeepass2binariesContents(entry);
}); });
}); });
group('kdbx4 attachment', () { group('kdbx4 attachment', () {
test('read binary', () async { test('read binary', () async {
final file = final file =
await TestUtil.readKdbxFile('test/keepass2kdbx4binaries.kdbx'); await TestUtil.readKdbxFile('test/keepass2kdbx4binaries.kdbx');
void expectBinary(KdbxEntry entry, String key, dynamic matcher) {
final binaries = entry.binaryEntries;
expect(binaries, hasLength(1));
final binary = binaries.first;
expect(binary.key.key, key);
expect(binary.value.value, matcher);
}
expect(file.body.rootGroup.entries, hasLength(2)); expect(file.body.rootGroup.entries, hasLength(2));
expectBinary(file.body.rootGroup.entries.first, 'example2.txt', expectBinary(file.body.rootGroup.entries.first, 'example2.txt',
@ -54,6 +67,17 @@ void main() {
hasLength(7092)); hasLength(7092));
}); });
}); });
test('read, write, read', () async {
final fileRead =
await TestUtil.readKdbxFile('test/keepass2kdbx4binaries.kdbx');
final saved = await fileRead.save();
final file = await TestUtil.readKdbxFileBytes(saved);
expect(file.body.rootGroup.entries, hasLength(2));
expectBinary(file.body.rootGroup.entries.first, 'example2.txt',
IsUtf8String('content2 example\n\n'));
expectBinary(
file.body.rootGroup.entries.last, 'keepasslogo.jpeg', hasLength(7092));
});
} }
class IsUtf8String extends CustomMatcher { class IsUtf8String extends CustomMatcher {

Loading…
Cancel
Save