9 use Crypt
::Misc
0.029 qw(decode_b64 encode_b64);
10 use File
::KDBX
::Constants
qw(:key_file);
12 use File
::Temp
qw(tempfile);
13 use Test
::More
1.001004_001
;
15 subtest
'Primitives' => sub {
16 my $pkey = File
::KDBX
::Key-
>new('password');
17 isa_ok
$pkey, 'File::KDBX::Key::Password';
18 is $pkey->raw_key, decode_b64
('XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg='),
19 'Can calculate raw key from password' or diag encode_b64
($pkey->raw_key);
21 my $fkey = File
::KDBX
::Key-
>new(\'password
');
22 isa_ok $fkey, 'File
::KDBX
::Key
::File
';
23 is $fkey->raw_key, decode_b64('XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg
='),
24 'Can calculate raw key from file
' or diag encode_b64($fkey->raw_key);
26 my $ckey = File::KDBX::Key->new([
30 File::KDBX::Key::File->new(testfile(qw{keys hashed.key})),
32 isa_ok
$ckey, 'File::KDBX::Key::Composite';
33 is $ckey->raw_key, decode_b64
('FLV8/zOT9mEL8QKkzizq7mJflnb25ITblIPq608MGrk='),
34 'Can calculate raw key from composite' or diag encode_b64
($ckey->raw_key);
38 [KEY_FILE_TYPE_XML
, 'xmlv1.key', 'OF9tj+tfww1kHNWQaJlZWIlBdoTVXOazP8g/vZK7NcI=', '1.0'],
39 [KEY_FILE_TYPE_XML
, 'xmlv2.key', 'OF9tj+tfww1kHNWQaJlZWIlBdoTVXOazP8g/vZK7NcI=', '2.0'],
40 [KEY_FILE_TYPE_BINARY
, 'binary.key', 'QlkDxuYbDPDpDXdK1470EwVBL+AJBH2gvPA9lxNkFEk='],
41 [KEY_FILE_TYPE_HEX
, 'hex.key', 'QlkDxuYbDPDpDXdK1470EwVBL+AJBH2gvPA9lxNkFEk='],
42 [KEY_FILE_TYPE_HASHED
, 'hashed.key', '8vAO4mrMeq6iCa1FHeWm/Mj5al8HIv2ajqsqsSeUC6U='],
45 subtest
"Load $type key file" => sub {
46 my ($type, $filename, $expected_key, $version) = @_;
48 my $key = File
::KDBX
::Key
::File-
>new(testfile
('keys', $filename));
49 is $key->raw_key, decode_b64
($expected_key),
50 "Can calculate raw key from $type file" or diag encode_b64
($key->raw_key);
51 is $key->type, $type, "File type is detected as $type";
52 is $key->version, $version, "File version is detected as $version" if defined $version;
55 subtest
"Save $type key file" => sub {
56 my ($type, $filename, $expected_key, $version) = @_;
58 my ($fh, $filepath) = tempfile
('keyfile-XXXXXX', TMPDIR
=> 1, UNLINK
=> 1);
61 my $key = File
::KDBX
::Key
::File-
>new(
62 filepath
=> $filepath,
65 raw_key
=> decode_b64
($expected_key),
68 my $e = exception
{ $key->save };
70 if ($type == KEY_FILE_TYPE_HASHED
) {
71 like
$e, qr/invalid type/i, "Cannot save $type file";
74 is $e, undef, "Save $type file";
76 my $key2 = File
::KDBX
::Key
::File-
>new($filepath);
77 is $key2->type, $key->type, 'Loaded key file has the same type';
78 is $key2->raw_key, $key->raw_key, 'Loaded key file has the same raw key';
82 subtest
'IO handle key files' => sub {
84 open(my $fh, '<', \
$buf) or die "open failed: $!\n";
86 my $key = File
::KDBX
::Key
::File-
>new($fh);
87 is $key->raw_key, decode_b64
('XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg='),
88 'Can calculate raw key from file handle' or diag encode_b64
($key->raw_key);
89 is $key->type, 'hashed', 'file type is detected as hashed';
91 my ($fh_save, $filepath) = tempfile
('keyfile-XXXXXX', TMPDIR
=> 1, UNLINK
=> 1);
92 is exception
{ $key->save(fh
=> $fh_save, type
=> KEY_FILE_TYPE_XML
) }, undef,
93 'Save key file using IO handle';
96 my $key2 = File
::KDBX
::Key
::File-
>new($filepath);
97 is $key2->type, KEY_FILE_TYPE_XML
, 'Loaded key file has the same type';
98 is $key2->filepath, $filepath, 'Loaded key remembers the filepath';
99 is $key2->raw_key, $key->raw_key, 'Loaded key file has the same raw key';
101 is $key2->raw_key, $key->raw_key, 'Raw key is the same when reloaded same file';
103 my $easy_raw_key = "\1" x
32;
104 $key->init(\
$easy_raw_key);
105 $key->save(filepath
=> $filepath);
108 is $key2->raw_key, "\1" x
32, 'Raw key is changed after reload';
111 subtest
'Key file error handling' => sub {
112 is exception
{ File
::KDBX
::Key
::File-
>new }, undef, 'Cannot instantiate uninitialized';
114 like exception
{ File
::KDBX
::Key
::File-
>init },
115 qr/^Missing key primitive/, 'Throw if no primitive is provided';
117 like exception
{ File
::KDBX
::Key
::File-
>new(testfile
(qw{keys nonexistent})) },
118 qr/^Failed to open key file/, 'Throw if file is missing';
120 like exception
{ File
::KDBX
::Key
::File-
>new({}) },
121 qr/^Unexpected primitive type/, 'Throw if primitive is the wrong type';