2 # ABSTRACT: Encrypted databases to store secret text and files
7 use Crypt
::PRNG
qw(random_bytes);
8 use Devel
::GlobalDestruction
;
9 use File
::KDBX
::Constants
qw(:all);
10 use File
::KDBX
::Error
;
12 use File
::KDBX
::Util
qw(:class :coercion :empty :uuid :search erase simple_expression_query snakify);
13 use Hash
::Util
::FieldHash
qw(fieldhashes);
14 use List
::Util
qw(any);
15 use Ref
::Util
qw(is_ref is_arrayref is_plain_hashref);
16 use Scalar
::Util
qw(blessed);
21 our $VERSION = '999.999'; # VERSION
24 fieldhashes \
my (%SAFE, %KEYS);
28 $kdbx = File
::KDBX-
>new(%attributes);
29 $kdbx = File
::KDBX-
>new($kdbx); # copy constructor
31 Construct a new L
<File
::KDBX
>.
39 return $_[0]->clone if @_ == 1 && blessed
$_[0] && $_[0]->isa($class);
41 my $self = bless {}, $class;
43 $self->_set_default_attributes if empty
$self;
47 sub DESTROY
{ local ($., $@, $!, $^E, $?); !in_global_destruction
and $_[0]->reset }
51 $kdbx = $kdbx->init(%attributes);
53 Initialize a L
<File
::KDBX
> with a new set of attributes
. Returns itself to allow
method chaining
.
55 This
is called by L
</new
>.
63 @$self{keys %args} = values %args;
72 Set a L
<File
::KDBX
> to an empty
state, ready to load a KDBX file
or build a new one
. Returns itself to allow
79 erase
$self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY
};
80 erase
$self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY
};
89 $kdbx_copy = $kdbx->clone;
90 $kdbx_copy = File
::KDBX-
>new($kdbx);
92 Clone a L
<File
::KDBX
>. The clone will be an exact copy
and completely independent of the original
.
99 return Storable
::dclone
($self);
102 sub STORABLE_freeze
{
108 return '', $copy, $KEYS{$self} // (), $SAFE{$self} // ();
119 @$self{keys %$clone} = values %$clone;
121 $SAFE{$self} = $safe;
123 for my $object (@{$self->all_groups}, @{$self->all_entries(history
=> 1)}) {
124 $object->kdbx($self);
128 ##############################################################################
138 $kdbx = KDBX
::File-
>load(\
$string, $key);
139 $kdbx = KDBX
::File-
>load(*IO
, $key);
140 $kdbx = KDBX
::File-
>load($filepath, $key);
141 $kdbx->load(...); # also instance method
143 $kdbx = File
::KDBX-
>load_string($string, $key);
144 $kdbx = File
::KDBX-
>load_string(\
$string, $key);
145 $kdbx->load_string(...); # also instance method
147 $kdbx = File
::KDBX-
>load_file($filepath, $key);
148 $kdbx->load_file(...); # also instance method
150 $kdbx = File
::KDBX-
>load_handle($fh, $key);
151 $kdbx = File
::KDBX-
>load_handle(*IO
, $key);
152 $kdbx->load_handle(...); # also instance method
154 Load a KDBX file from a string buffer
, IO handle
or file from a filesystem
.
156 L
<File
::KDBX
::Loader
> does the heavy lifting
.
160 sub load
{ shift-
>_loader->load(@_) }
161 sub load_string
{ shift-
>_loader->load_string(@_) }
162 sub load_file
{ shift-
>_loader->load_file(@_) }
163 sub load_handle
{ shift-
>_loader->load_handle(@_) }
167 $self = $self->new if !ref $self;
168 require File
::KDBX
::Loader
;
169 File
::KDBX
::Loader-
>new(kdbx
=> $self);
180 $kdbx->dump(\
$string, $key);
181 $kdbx->dump(*IO
, $key);
182 $kdbx->dump($filepath, $key);
184 $kdbx->dump_string(\
$string, $key);
185 \
$string = $kdbx->dump_string($key);
187 $kdbx->dump_file($filepath, $key);
189 $kdbx->dump_handle($fh, $key);
190 $kdbx->dump_handle(*IO
, $key);
192 Dump a KDBX file to a string buffer
, IO handle
or file
in a filesystem
.
194 L
<File
::KDBX
::Dumper
> does the heavy lifting
.
198 sub dump { shift-
>_dumper->dump(@_) }
199 sub dump_string
{ shift-
>_dumper->dump_string(@_) }
200 sub dump_file
{ shift-
>_dumper->dump_file(@_) }
201 sub dump_handle
{ shift-
>_dumper->dump_handle(@_) }
205 $self = $self->new if !ref $self;
206 require File
::KDBX
::Dumper
;
207 File
::KDBX
::Dumper-
>new(kdbx
=> $self);
210 ##############################################################################
212 =method user_agent_string
214 $string = $kdbx->user_agent_string;
216 Get a text string identifying the database client software
.
220 sub user_agent_string
{
222 sprintf('%s/%s (%s/%s; %s/%s; %s)',
223 __PACKAGE__
, $VERSION, @Config::Config
{qw(package version osname osvers archname)});
227 sig1
=> [KDBX_SIG1
, coerce
=> \
&to_number
],
228 sig2
=> [KDBX_SIG2_2
, coerce
=> \
&to_number
],
229 version
=> [KDBX_VERSION_3_1
, coerce
=> \
&to_number
],
231 inner_headers
=> [{}],
234 deleted_objects
=> [{}],
235 raw
=> [undef, coerce
=> \
&to_string
],
237 my %ATTRS_HEADERS = (
238 HEADER_COMMENT
() => ['', coerce
=> \
&to_string
],
239 HEADER_CIPHER_ID
() => [CIPHER_UUID_CHACHA20
, coerce
=> \
&to_uuid
],
240 HEADER_COMPRESSION_FLAGS
() => [COMPRESSION_GZIP
, coerce
=> sub { compression
($_[0]) }],
241 HEADER_MASTER_SEED
() => [sub { random_bytes
(32) }, coerce
=> \
&to_string
],
242 # HEADER_TRANSFORM_SEED() => sub { random_bytes(32) },
243 # HEADER_TRANSFORM_ROUNDS() => 100_000,
244 HEADER_ENCRYPTION_IV
() => [sub { random_bytes
(16) }, coerce
=> \
&to_string
],
245 # HEADER_INNER_RANDOM_STREAM_KEY() => sub { random_bytes(32) }, # 64?
246 HEADER_STREAM_START_BYTES
() => [sub { random_bytes
(32) }, coerce
=> \
&to_string
],
247 # HEADER_INNER_RANDOM_STREAM_ID() => STREAM_ID_CHACHA20,
248 HEADER_KDF_PARAMETERS
() => [sub {
250 KDF_PARAM_UUID
() => KDF_UUID_AES
,
251 KDF_PARAM_AES_ROUNDS
() => $_[0]->headers->{+HEADER_TRANSFORM_ROUNDS
} // KDF_DEFAULT_AES_ROUNDS
,
252 KDF_PARAM_AES_SEED
() => $_[0]->headers->{+HEADER_TRANSFORM_SEED
} // random_bytes
(32),
255 # HEADER_PUBLIC_CUSTOM_DATA() => sub { +{} },
258 generator
=> ['', coerce
=> \
&to_string
],
259 header_hash
=> ['', coerce
=> \
&to_string
],
260 database_name
=> ['', coerce
=> \
&to_string
],
261 database_name_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
262 database_description
=> ['', coerce
=> \
&to_string
],
263 database_description_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
264 default_username
=> ['', coerce
=> \
&to_string
],
265 default_username_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
266 maintenance_history_days
=> [0, coerce
=> \
&to_number
],
267 color
=> ['', coerce
=> \
&to_string
],
268 master_key_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
269 master_key_change_rec
=> [-1, coerce
=> \
&to_number
],
270 master_key_change_force
=> [-1, coerce
=> \
&to_number
],
271 # memory_protection => {},
272 custom_icons
=> [{}],
273 recycle_bin_enabled
=> [true
, coerce
=> \
&to_bool
],
274 recycle_bin_uuid
=> ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", coerce
=> \
&to_uuid
],
275 recycle_bin_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
276 entry_templates_group
=> ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", coerce
=> \
&to_uuid
],
277 entry_templates_group_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
278 last_selected_group
=> ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", coerce
=> \
&to_uuid
],
279 last_top_visible_group
=> ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", coerce
=> \
&to_uuid
],
280 history_max_items
=> [HISTORY_DEFAULT_MAX_ITEMS
, coerce
=> \
&to_number
],
281 history_max_size
=> [HISTORY_DEFAULT_MAX_SIZE
, coerce
=> \
&to_number
],
282 settings_changed
=> [sub { gmtime }, coerce
=> \
&to_time
],
286 my %ATTRS_MEMORY_PROTECTION = (
287 protect_title
=> [false
, coerce
=> \
&to_bool
],
288 protect_username
=> [false
, coerce
=> \
&to_bool
],
289 protect_password
=> [true
, coerce
=> \
&to_bool
],
290 protect_url
=> [false
, coerce
=> \
&to_bool
],
291 protect_notes
=> [false
, coerce
=> \
&to_bool
],
292 # auto_enable_visual_hiding => false,
295 while (my ($attr, $default) = each %ATTRS) {
296 has $attr => @$default;
298 while (my ($attr, $default) = each %ATTRS_HEADERS) {
299 has $attr => @$default, store
=> 'headers';
301 while (my ($attr, $default) = each %ATTRS_META) {
302 has $attr => @$default, store
=> 'meta';
304 while (my ($attr, $default) = each %ATTRS_MEMORY_PROTECTION) {
305 has $attr => @$default, store
=> 'memory_protection';
309 HEADER_TRANSFORM_SEED
,
310 HEADER_TRANSFORM_ROUNDS
,
311 HEADER_INNER_RANDOM_STREAM_KEY
,
312 HEADER_INNER_RANDOM_STREAM_ID
,
313 HEADER_PUBLIC_CUSTOM_DATA
,
315 sub _set_default_attributes
{
317 $self->$_ for keys %ATTRS, keys %ATTRS_HEADERS, keys %ATTRS_META, keys %ATTRS_MEMORY_PROTECTION,
321 =method memory_protection
323 \
%settings = $kdbx->memory_protection
324 $kdbx->memory_protection(\
%settings);
326 $bool = $kdbx->memory_protection($string_key);
327 $kdbx->memory_protection($string_key => $bool);
329 Get
or set memory protection settings
. This globally
(for the whole database
) configures whether
and which of
330 the standard strings should be memory-protected
. The
default setting
is to memory-protect only I
<Password
>
333 Memory protection can be toggled individually
for each entry string
, and individual settings
take precedence
334 over these global settings
.
338 sub memory_protection
{
340 $self->{meta
}{memory_protection
} = shift if @_ == 1 && is_plain_hashref
($_[0]);
341 return $self->{meta
}{memory_protection
} //= {} if !@_;
343 my $string_key = shift;
344 my $key = 'protect_' . lc($string_key);
346 $self->meta->{memory_protection
}{$key} = shift if @_;
347 $self->meta->{memory_protection
}{$key};
350 =method minimum_version
352 $version = $kdbx->minimum_version;
354 Determine the minimum file version required to save a database losslessly
. Using certain databases features
355 might increase this value
. For example
, setting the KDF to Argon2 will increase the minimum version to at
356 least C
<KDBX_VERSION_4_0
> (i
.e
. C
<0x00040000>) because Argon2 was introduced with KDBX4
.
358 This
method never returns less than C
<KDBX_VERSION_3_1
> (i
.e
. C
<0x00030001>). That file version
is so
359 ubiquitious
and well-supported
, there are seldom reasons to
dump in a lesser format nowadays
.
361 B
<WARNING
:> If you
dump a database with a minimum version higher than the current L
</version
>, the dumper will
362 typically issue a warning
and automatically upgrade the database
. This seems like the safest behavior
in order
363 to avoid data loss
, but lower versions have the benefit of being compatible with more software
. It
is possible
364 to prevent auto-upgrades by explicitly telling the dumper which version to
use, but you
do run the risk of
365 data loss
. A database will never be automatically downgraded
.
369 sub minimum_version
{
372 return KDBX_VERSION_4_1
if any
{
373 nonempty
$_->{last_modification_time
}
374 } values %{$self->custom_data};
376 return KDBX_VERSION_4_1
if any
{
377 nonempty
$_->{name
} || nonempty
$_->{last_modification_time
}
378 } values %{$self->custom_icons};
380 return KDBX_VERSION_4_1
if any
{
381 nonempty
$_->previous_parent_group || nonempty
$_->tags ||
382 any
{ nonempty
$_->{last_modification_time
} } values %{$_->custom_data}
383 } @{$self->all_groups};
385 return KDBX_VERSION_4_1
if any
{
386 nonempty
$_->previous_parent_group || (defined $_->quality_check && !$_->quality_check) ||
387 any
{ nonempty
$_->{last_modification_time
} } values %{$_->custom_data}
388 } @{$self->all_entries(history
=> 1)};
390 return KDBX_VERSION_4_0
if $self->kdf->uuid ne KDF_UUID_AES
;
392 return KDBX_VERSION_4_0
if nonempty
$self->public_custom_data;
394 return KDBX_VERSION_4_0
if any
{
395 nonempty
$_->custom_data
396 } @{$self->all_groups}, @{$self->all_entries(history
=> 1)};
398 return KDBX_VERSION_3_1
;
401 ##############################################################################
405 $kdbx->add_group($group, %options);
406 $kdbx->add_group(%group_attributes, %options);
408 Add a group to a database
. This
is equivalent to identifying a parent group
and calling
409 L
<File
::KDBX
::Group
/add_group
> on the parent group
, forwarding the arguments
. Available options
:
412 * C<group> (aka C<parent>) - Group (object or group UUID) to add the group to (default: root group)
418 my $group = @_ % 2 == 1 ? shift : undef;
421 # find the right group to add the group to
422 my $parent = delete $args{group
} // delete $args{parent
} // $self->root;
423 ($parent) = $self->find_groups({uuid
=> $parent}) if !ref $parent;
424 $parent or throw
'Invalid group';
426 return $parent->add_group(defined $group ? $group : (), %args, kdbx
=> $self);
432 require File
::KDBX
::Group
;
433 return File
::KDBX
::Group-
>wrap($group, $self);
438 $group = $kdbx->root;
441 Get
or set a database
's root group. You don't necessarily need to explicitly create
or set a root group
442 because it autovivifies
when adding entries
and groups to the database
.
444 Every database
has only a single root group at a
time. Some old KDB files might have multiple root groups
.
445 When reading such files
, a single implicit root group
is created to contain the other explicit groups
. When
446 writing to such a format
, if the root group looks like it was implicitly created then it won
't be written and
447 the resulting file might have multiple root groups. This allows working with older files without changing
448 their written internal structure while still adhering to modern semantics while the database is opened.
450 B<WARNING:> The root group of a KDBX database contains all of the database's entries
and other groups
. If you
451 replace the root group
, you are essentially replacing the entire database contents with something
else.
458 $self->{root
} = $self->_wrap_group(@_);
459 $self->{root
}->kdbx($self);
461 $self->{root
} //= $self->_implicit_root;
462 return $self->_wrap_group($self->{root
});
467 return [] if !$self->{root
};
468 return $self->_has_implicit_root ? $self->root->groups : [$self->root];
471 sub _has_implicit_root
{
473 my $root = $self->root;
474 my $temp = __PACKAGE__-
>_implicit_root;
475 # If an implicit root group has been changed in any significant way, it is no longer implicit.
476 return $root->name eq $temp->name &&
477 $root->is_expanded ^ $temp->is_expanded &&
478 $root->notes eq $temp->notes &&
479 !@{$root->entries} &&
480 !defined $root->custom_icon_uuid &&
481 !keys %{$root->custom_data} &&
482 $root->icon_id == $temp->icon_id &&
483 $root->expires ^ $temp->expires &&
484 $root->default_auto_type_sequence eq $temp->default_auto_type_sequence &&
485 !defined $root->enable_auto_type &&
486 !defined $root->enable_searching;
491 require File
::KDBX
::Group
;
492 return File
::KDBX
::Group-
>new(
495 notes
=> 'Added as an implicit root group by '.__PACKAGE__
.'.',
496 ref $self ? (kdbx
=> $self) : (),
502 \
@groups = $kdbx->all_groups(%options);
503 \
@groups = $kdbx->all_groups($base_group, %options);
505 Get all groups deeply
in a database
, or all groups within a specified base group
, in a flat array
. Supported
509 * C<base> - Only include groups within a base group (same as C<$base_group>) (default: root)
510 * C<include_base> - Include the base group in the results (default: true)
516 my %args = @_ % 2 == 0 ? @_ : (base
=> shift, @_);
517 my $base = $args{base
} // $self->root;
519 my @groups = $args{include_base
} // 1 ? $self->_wrap_group($base) : ();
521 for my $subgroup (@{$base->{groups
} || []}) {
522 my $more = $self->all_groups($subgroup);
523 push @groups, @$more;
529 =method trace_lineage
531 \
@lineage = $kdbx->trace_lineage($group);
532 \
@lineage = $kdbx->trace_lineage($group, $base_group);
533 \
@lineage = $kdbx->trace_lineage($entry);
534 \
@lineage = $kdbx->trace_lineage($entry, $base_group);
536 Get the direct line of ancestors from C
<$base_group> (default: the root group
) to a group
or entry
. The
537 lineage includes the base group but I
<not> the target group
or entry
. Returns C
<undef> if the target
is not in
538 the database structure
.
545 return $object->lineage(@_);
553 push @lineage, $self->root if !@lineage;
554 my $base = $lineage[-1] or return [];
556 my $uuid = $object->uuid;
557 return \
@lineage if any
{ $_->uuid eq $uuid } @{$base->groups || []}, @{$base->entries || []};
559 for my $subgroup (@{$base->groups || []}) {
560 my $result = $self->_trace_lineage($object, @lineage, $subgroup);
561 return $result if $result;
567 @groups = $kdbx->find_groups($query, %options);
569 Find all groups deeply that match to a query
. Options are the same as
for L
</all_groups
>.
571 See L
</QUERY
> for a description of what C
<$query> can be
.
577 my $query = shift or throw
'Must provide a query';
581 include_base
=> $args{include_base
},
583 return @{search
($self->all_groups(%all_groups), is_arrayref
($query) ? @$query : $query)};
591 ##############################################################################
595 $kdbx->add_entry($entry, %options);
596 $kdbx->add_entry(%entry_attributes, %options);
598 Add a entry to a database
. This
is equivalent to identifying a parent group
and calling
599 L
<File
::KDBX
::Group
/add_entry
> on the parent group
, forwarding the arguments
. Available options
:
602 * C<group> (aka C<parent>) - Group (object or group UUID) to add the entry to (default: root group)
608 my $entry = @_ % 2 == 1 ? shift : undef;
611 # find the right group to add the entry to
612 my $parent = delete $args{group
} // delete $args{parent
} // $self->root;
613 ($parent) = $self->find_groups({uuid
=> $parent}) if !ref $parent;
614 $parent or throw
'Invalid group';
616 return $parent->add_entry(defined $entry ? $entry : (), %args, kdbx
=> $self);
622 require File
::KDBX
::Entry
;
623 return File
::KDBX
::Entry-
>wrap($entry, $self);
628 \
@entries = $kdbx->all_entries(%options);
629 \
@entries = $kdbx->all_entries($base_group, %options);
631 Get entries deeply
in a database
, in a flat array
. Supported options
:
634 * C<base> - Only include entries within a base group (same as C<$base_group>) (default: root)
635 * C<auto_type> - Only include entries with auto-type enabled (default: false, include all)
636 * C<search> - Only include entries within groups with search enabled (default: false, include all)
637 * C<history> - Also include historical entries (default: false, include only active entries)
643 my %args = @_ % 2 == 0 ? @_ : (base
=> shift, @_);
645 my $base = $args{base
} // $self->root;
646 my $history = $args{history
};
647 my $search = $args{search
};
648 my $auto_type = $args{auto_type
};
650 my $enable_auto_type = $base->{enable_auto_type
} // true
;
651 my $enable_searching = $base->{enable_searching
} // true
;
654 if ((!$search || $enable_searching) && (!$auto_type || $enable_auto_type)) {
656 map { $self->_wrap_entry($_) }
657 grep { !$auto_type || $_->{auto_type
}{enabled
} }
658 map { $_, $history ? @{$_->{history
} || []} : () }
659 @{$base->{entries
} || []};
662 for my $subgroup (@{$base->{groups
} || []}) {
663 my $more = $self->all_entries($subgroup,
664 auto_type
=> $auto_type,
668 push @entries, @$more;
676 =method find_entries_simple
678 @entries = $kdbx->find_entries($query, %options);
680 @entries = $kdbx->find_entries_simple($expression, \
@fields, %options);
681 @entries = $kdbx->find_entries_simple($expression, $operator, \
@fields, %options);
683 Find all entries deeply that match a query
. Options are the same as
for L
</all_entries
>.
685 See L
</QUERY
> for a description of what C
<$query> can be
.
691 my $query = shift or throw
'Must provide a query';
695 auto_type
=> $args{auto_type
},
696 search
=> $args{search
},
697 history
=> $args{history
},
699 my $limit = delete $args{limit
};
700 if (defined $limit) {
701 return @{search_limited
($self->all_entries(%all_entries), is_arrayref
($query) ? @$query : $query, $limit)};
704 return @{search
($self->all_entries(%all_entries), is_arrayref
($query) ? @$query : $query)};
708 sub find_entries_simple
{
711 my $op = @_ && !is_ref
($_[0]) ? shift : undef;
713 is_arrayref
($fields) or throw
q{Usage: find_entries_simple($expression, [$op,] \@fields)};
714 return $self->find_entries([\
$text, $op, $fields], @_);
717 ##############################################################################
721 \
%icon = $kdbx->custom_icon($uuid);
722 $kdbx->custom_icon($uuid => \
%icon);
723 $kdbx->custom_icon(%icon);
724 $kdbx->custom_icon(uuid
=> $value, %icon);
731 my %args = @_ == 2 ? (uuid
=> shift, value
=> shift)
732 : @_ % 2 == 1 ? (uuid
=> shift, @_) : @_;
734 if (!$args{key
} && !$args{value
}) {
735 my %standard = (key
=> 1, value
=> 1, last_modification_time
=> 1);
736 my @other_keys = grep { !$standard{$_} } keys %args;
737 if (@other_keys == 1) {
738 my $key = $args{key
} = $other_keys[0];
739 $args{value
} = delete $args{$key};
743 my $key = $args{key
} or throw
'Must provide a custom_icons key to access';
745 return $self->{meta
}{custom_icons
}{$key} = $args{value
} if is_plain_hashref
($args{value
});
747 while (my ($field, $value) = each %args) {
748 $self->{meta
}{custom_icons
}{$key}{$field} = $value;
750 return $self->{meta
}{custom_icons
}{$key};
753 =method custom_icon_data
755 $image_data = $kdbx->custom_icon_data($uuid);
761 sub custom_icon_data
{
763 my $uuid = shift // return;
764 return if !exists $self->custom_icons->{$uuid};
765 return $self->custom_icons->{$uuid}{data
};
768 =method add_custom_icon
770 $uuid = $kdbx->add_custom_icon($image_data, %attributes);
772 Add a custom icon
and get its UUID
. If
not provided
, a random UUID will be generated
. Possible attributes
:
775 * C<uuid> - Icon UUID
776 * C<name> - Name of the icon (text, KDBX4.1+)
777 * C<last_modification_time> - Just what it says (datetime, KDBX4.1+)
781 sub add_custom_icon
{
783 my $img = shift or throw
'Must provide image data';
786 my $uuid = $args{uuid
} // generate_uuid
(sub { !$self->custom_icons->{$_} });
787 $self->custom_icons->{$uuid} = {
795 =method remove_custom_icon
797 $kdbx->remove_custom_icon($uuid);
799 Remove a custom icon
.
803 sub remove_custom_icon
{
806 delete $self->custom_icons->{$uuid};
809 ##############################################################################
813 \
%all_data = $kdbx->custom_data;
814 $kdbx->custom_data(\
%all_data);
816 \
%data = $kdbx->custom_data($key);
817 $kdbx->custom_data($key => \
%data);
818 $kdbx->custom_data(%data);
819 $kdbx->custom_data(key
=> $value, %data);
821 Get
and set custom data
. Custom data
is metadata associated with a database
.
823 Each data item can have a few attributes associated with it
.
826 * C<key> - A unique text string identifier used to look up the data item (required)
827 * C<value> - A text string value (required)
828 * C<last_modification_time> (optional, KDBX4.1+)
834 $self->{meta
}{custom_data
} = shift if @_ == 1 && is_plain_hashref
($_[0]);
835 return $self->{meta
}{custom_data
} //= {} if !@_;
837 my %args = @_ == 2 ? (key
=> shift, value
=> shift)
838 : @_ % 2 == 1 ? (key
=> shift, @_) : @_;
840 if (!$args{key
} && !$args{value
}) {
841 my %standard = (key
=> 1, value
=> 1, last_modification_time
=> 1);
842 my @other_keys = grep { !$standard{$_} } keys %args;
843 if (@other_keys == 1) {
844 my $key = $args{key
} = $other_keys[0];
845 $args{value
} = delete $args{$key};
849 my $key = $args{key
} or throw
'Must provide a custom_data key to access';
851 return $self->{meta
}{custom_data
}{$key} = $args{value
} if is_plain_hashref
($args{value
});
853 while (my ($field, $value) = each %args) {
854 $self->{meta
}{custom_data
}{$key}{$field} = $value;
856 return $self->{meta
}{custom_data
}{$key};
859 =method custom_data_value
861 $value = $kdbx->custom_data_value($key);
863 Exactly the same as L
</custom_data
> except returns just the custom data
's value rather than a structure of
864 attributes. This is a shortcut for:
866 my $data = $kdbx->custom_data($key);
867 my $value = defined $data ? $data->{value} : undef;
871 sub custom_data_value {
873 my $data = $self->custom_data(@_) // return;
874 return $data->{value};
877 =method public_custom_data
879 \%all_data = $kdbx->public_custom_data;
880 $kdbx->public_custom_data(\%all_data);
882 $value = $kdbx->public_custom_data($key);
883 $kdbx->public_custom_data($key => $value);
885 Get and set public custom data. Public custom data is similar to custom data but different in some important
886 ways. Public custom data:
889 * can store strings, booleans and up to 64-bit integer values (custom data can only store text values)
890 * is NOT encrypted within a KDBX file (hence the "public" part of the name)
891 * is a plain hash/dict of key-value pairs with no other associated fields (like modification times)
895 sub public_custom_data {
897 $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA} = shift if @_ == 1 && is_plain_hashref($_[0]);
898 return $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA} //= {} if !@_;
900 my $key = shift or throw 'Must provide a public_custom_data key to access
';
901 $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA}{$key} = shift if @_;
902 return $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA}{$key};
905 ##############################################################################
912 # my %options = @_; # prefer_old / prefer_new
913 # $other->merge_from($self);
920 # die 'Not implemented
';
923 ##############################################################################
925 =method resolve_reference
927 $string = $kdbx->resolve_reference($reference);
928 $string = $kdbx->resolve_reference($wanted, $search_in, $expression);
930 Resolve a L<field reference|https://keepass.info/help/base/fieldrefs.html>. A field reference is a kind of
931 string placeholder. You can use a field reference to refer directly to a standard field within an entry. Field
932 references are resolved automatically while expanding entry strings (i.e. replacing placeholders), but you can
933 use this method to resolve on-the-fly references that aren't part of any actual string
in the database
.
935 If the reference
does not resolve to any field
, C
<undef> is returned
. If the reference resolves to multiple
936 fields
, only the first one
is returned
(in the same order as L
</all_entries
>). To avoid ambiguity
, you can
937 refer to a specific entry by its UUID
.
939 The syntax of a reference
is: C
<< {REF
:<WantedField
>@<SearchIn
>:<Text
>} >>. C
<Text
> is a
940 L
</"Simple Expression">. C
<WantedField
> and C
<SearchIn
> are both single character codes representing a field
:
949 * C<O> - Other custom strings
951 Since C<O> does not represent any specific field, it cannot be used as the C<WantedField>.
955 To get the value of the I<UserName> string of the first entry with "My Bank" in the title:
957 my $username = $kdbx->resolve_reference('{REF:U@T:"My Bank"}');
958 # OR the {REF:...} wrapper is optional
959 my $username = $kdbx->resolve_reference('U@T:"My Bank"');
960 # OR separate the arguments
961 my $username = $kdbx->resolve_reference(U => T => '"My Bank"');
963 Note how the text is a L</"Simple Expression">, so search terms with spaces must be surrounded in double
966 To get the I<Password> string of a specific entry (identified by its UUID):
968 my $password = $kdbx->resolve_reference('{REF:P@I:46C9B1FFBD4ABC4BBB260C6190BAD20C}');
972 sub resolve_reference
{
974 my $wanted = shift // return;
975 my $search_in = shift;
978 if (!defined $text) {
979 $wanted =~ s/^\{REF:([^\}]+)\}$/$1/i;
980 ($wanted, $search_in, $text) = $wanted =~ /^([TUPANI])\@([TUPANIO]):(.*)$/i;
982 $wanted && $search_in && nonempty
($text) or return;
985 T
=> 'expanded_title',
986 U
=> 'expanded_username',
987 P
=> 'expanded_password',
989 N
=> 'expanded_notes',
991 O
=> 'other_strings',
993 $wanted = $fields{$wanted} or return;
994 $search_in = $fields{$search_in} or return;
996 my $query = $search_in eq 'uuid' ? query
($search_in => uuid
($text))
997 : simple_expression_query
($text, '=~', $search_in);
999 my ($entry) = $self->find_entries($query, limit
=> 1);
1002 return $entry->$wanted;
1005 our %PLACEHOLDERS = (
1006 # placeholder => sub { my ($entry, $arg) = @_; ... };
1007 'TITLE' => sub { $_[0]->expanded_title },
1008 'USERNAME' => sub { $_[0]->expanded_username },
1009 'PASSWORD' => sub { $_[0]->expanded_password },
1010 'NOTES' => sub { $_[0]->expanded_notes },
1011 'S:' => sub { $_[0]->string_value($_[1]) },
1012 'URL' => sub { $_[0]->expanded_url },
1013 'URL:RMVSCM' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
1014 'URL:WITHOUTSCHEME' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
1015 'URL:SCM' => sub { (split_url
($_[0]->url))[0] },
1016 'URL:SCHEME' => sub { (split_url
($_[0]->url))[0] }, # non-standard
1017 'URL:HOST' => sub { (split_url
($_[0]->url))[2] },
1018 'URL:PORT' => sub { (split_url
($_[0]->url))[3] },
1019 'URL:PATH' => sub { (split_url
($_[0]->url))[4] },
1020 'URL:QUERY' => sub { (split_url
($_[0]->url))[5] },
1021 'URL:HASH' => sub { (split_url
($_[0]->url))[6] }, # non-standard
1022 'URL:FRAGMENT' => sub { (split_url
($_[0]->url))[6] }, # non-standard
1023 'URL:USERINFO' => sub { (split_url
($_[0]->url))[1] },
1024 'URL:USERNAME' => sub { (split_url
($_[0]->url))[7] },
1025 'URL:PASSWORD' => sub { (split_url
($_[0]->url))[8] },
1026 'UUID' => sub { local $_ = format_uuid
($_[0]->uuid); s/-//g; $_ },
1027 'REF:' => sub { $_[0]->kdbx->resolve_reference($_[1]) },
1028 'INTERNETEXPLORER' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('iexplore') },
1029 'FIREFOX' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('firefox') },
1030 'GOOGLECHROME' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('google-chrome') },
1031 'OPERA' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('opera') },
1032 'SAFARI' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('safari') },
1033 'APPDIR' => sub { load_optional
('FindBin'); $FindBin::Bin
},
1034 'GROUP' => sub { my $p = $_[0]->parent; $p ? $p->name : undef },
1035 'GROUP_PATH' => sub { $_[0]->path },
1036 'GROUP_NOTES' => sub { my $p = $_[0]->parent; $p ? $p->notes : undef },
1045 'ENV:' => sub { $ENV{$_[1]} },
1046 'ENV_DIRSEP' => sub { load_optional
('File::Spec')->catfile('', '') },
1047 'ENV_PROGRAMFILES_X86' => sub { $ENV{'ProgramFiles(x86)'} || $ENV{'ProgramFiles'} },
1050 'DT_SIMPLE' => sub { localtime-
>strftime('%Y%m%d%H%M%S') },
1051 'DT_YEAR' => sub { localtime-
>strftime('%Y') },
1052 'DT_MONTH' => sub { localtime-
>strftime('%m') },
1053 'DT_DAY' => sub { localtime-
>strftime('%d') },
1054 'DT_HOUR' => sub { localtime-
>strftime('%H') },
1055 'DT_MINUTE' => sub { localtime-
>strftime('%M') },
1056 'DT_SECOND' => sub { localtime-
>strftime('%S') },
1057 'DT_UTC_SIMPLE' => sub { gmtime-
>strftime('%Y%m%d%H%M%S') },
1058 'DT_UTC_YEAR' => sub { gmtime-
>strftime('%Y') },
1059 'DT_UTC_MONTH' => sub { gmtime-
>strftime('%m') },
1060 'DT_UTC_DAY' => sub { gmtime-
>strftime('%d') },
1061 'DT_UTC_HOUR' => sub { gmtime-
>strftime('%H') },
1062 'DT_UTC_MINUTE' => sub { gmtime-
>strftime('%M') },
1063 'DT_UTC_SECOND' => sub { gmtime-
>strftime('%S') },
1070 'HMACOTP' => sub { $_[0]->hmac_otp },
1071 'TIMEOTP' => sub { $_[0]->time_otp },
1072 'C:' => sub { '' }, # comment
1080 ##############################################################################
1086 Encrypt all protected strings
in a database
. The encrypted strings are stored
in a L
<File
::KDBX
::Safe
>
1087 associated with the database
and the actual strings will be replaced with C
<undef> to indicate their protected
1088 state. Returns itself to allow
method chaining
.
1094 $SAFE{$self} = shift if @_;
1098 sub _remove_safe
{ delete $SAFE{$_[0]} }
1103 $self->_safe and return $self;
1107 my $entries = $self->all_entries(history
=> 1);
1108 for my $entry (@$entries) {
1109 push @strings, grep { $_->{protect
} } values %{$entry->{strings
} || {}};
1112 $self->_safe(File
::KDBX
::Safe-
>new(\
@strings));
1121 Decrypt all protected strings
in a database
, replacing C
<undef> placeholders with unprotected
values. Returns
1122 itself to allow
method chaining
.
1128 my $safe = $self->_safe or return $self;
1131 $self->_remove_safe;
1136 =method unlock_scoped
1138 $guard = $kdbx->unlock_scoped;
1140 Unlock a database temporarily
, relocking
when the guard
is released
(typically at the end of a scope
). Returns
1141 C
<undef> if the database
is already unlocked
.
1143 See L
</lock> and L</unlock
>.
1148 throw
'Programmer error: Cannot call unlock_scoped in void context' if !defined wantarray;
1150 return if !$self->is_locked;
1151 require Scope
::Guard
;
1152 my $guard = Scope
::Guard-
>new(sub { $self->lock });
1159 $string = $kdbx->peek(\
%string);
1160 $string = $kdbx->peek(\
%binary);
1162 Peek at the value of a protected string
or binary without unlocking the whole database
. The argument can be
1163 a string
or binary hashref as returned by L
<File
::KDBX
::Entry
/string> or L<File::KDBX::Entry/binary
>.
1170 my $safe = $self->_safe or return;
1171 return $safe->peek($string);
1176 $bool = $kdbx->is_locked;
1178 Get whether
or not a database
's strings are memory-protected. If this is true, then some or all of the
1179 protected strings within the database will be unavailable (literally have C<undef> values) until L</unlock> is
1184 sub is_locked { $_[0]->_safe ? 1 : 0 }
1186 ##############################################################################
1188 =method randomize_seeds
1190 $kdbx->randomize_seeds;
1192 Set various keys, seeds and IVs to random values. These values are used by the cryptographic functions that
1193 secure the database when dumped. The attributes that will be randomized are:
1197 * L</inner_random_stream_key>
1199 * L</stream_start_bytes>
1200 * L</transform_seed>
1202 Randomizing these values has no effect on a loaded database. These are only used when a database is dumped.
1203 You normally do not need to call this method explicitly because the dumper does it explicitly by default.
1207 sub randomize_seeds {
1209 $self->encryption_iv(random_bytes(16));
1210 $self->inner_random_stream_key(random_bytes(64));
1211 $self->master_seed(random_bytes(32));
1212 $self->stream_start_bytes(random_bytes(32));
1213 $self->transform_seed(random_bytes(32));
1216 ##############################################################################
1221 $key = $kdbx->key($key);
1222 $key = $kdbx->key($primitive);
1224 Get or set a L<File::KDBX::Key>. This is the master key (i.e. a password or a key file that can decrypt
1225 a database). See L<File::KDBX::Key/new> for an explanation of what the primitive can be.
1227 You generally don't need to call this directly because you can provide the key directly to the loader
or
1228 dumper
when loading
or saving a KDBX file
.
1234 $KEYS{$self} = File
::KDBX
::Key-
>new(@_) if @_;
1238 =method composite_key
1240 $key = $kdbx->composite_key($key);
1241 $key = $kdbx->composite_key($primitive);
1243 Construct a L
<File
::KDBX
::Key
::Composite
> from a primitive
. See L
<File
::KDBX
::Key
/new
> for an explanation of
1244 what the primitive can be
. If the primitive
does not represent a composite key
, it will be wrapped
.
1246 You generally don
't need to call this directly. The parser and writer use it to transform a master key into
1247 a raw encryption key.
1253 require File::KDBX::Key::Composite;
1254 return File::KDBX::Key::Composite->new(@_);
1259 $kdf = $kdbx->kdf(%options);
1260 $kdf = $kdbx->kdf(\%parameters, %options);
1262 Get a L<File::KDBX::KDF> (key derivation function).
1267 * C<params> - KDF parameters, same as C<\%parameters> (default: value of L</kdf_parameters>)
1273 my %args = @_ % 2 == 1 ? (params => shift, @_) : @_;
1275 my $params = $args{params};
1276 my $compat = $args{compatible} // 1;
1278 $params //= $self->kdf_parameters;
1279 $params = {%{$params || {}}};
1281 if (empty $params || !defined $params->{+KDF_PARAM_UUID}) {
1282 $params->{+KDF_PARAM_UUID} = KDF_UUID_AES;
1284 if ($params->{+KDF_PARAM_UUID} eq KDF_UUID_AES) {
1285 # AES_CHALLENGE_RESPONSE is equivalent to AES if there are no challenge-response keys, and since
1286 # non-KeePassXC implementations don't support challenge-response
keys anyway
, there
's no problem with
1287 # always using AES_CHALLENGE_RESPONSE for all KDBX4+ databases.
1288 # For compatibility, we should not *write* AES_CHALLENGE_RESPONSE, but the dumper handles that.
1289 if ($self->version >= KDBX_VERSION_4_0) {
1290 $params->{+KDF_PARAM_UUID} = KDF_UUID_AES_CHALLENGE_RESPONSE;
1292 $params->{+KDF_PARAM_AES_SEED} //= $self->transform_seed;
1293 $params->{+KDF_PARAM_AES_ROUNDS} //= $self->transform_rounds;
1296 require File::KDBX::KDF;
1297 return File::KDBX::KDF->new(%$params);
1300 sub transform_seed {
1302 $self->headers->{+HEADER_TRANSFORM_SEED} =
1303 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} = shift if @_;
1304 $self->headers->{+HEADER_TRANSFORM_SEED} =
1305 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} //= random_bytes(32);
1308 sub transform_rounds {
1310 $self->headers->{+HEADER_TRANSFORM_ROUNDS} =
1311 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} = shift if @_;
1312 $self->headers->{+HEADER_TRANSFORM_ROUNDS} =
1313 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} //= 100_000;
1318 $cipher = $kdbx->cipher(key => $key);
1319 $cipher = $kdbx->cipher(key => $key, iv => $iv, uuid => $uuid);
1321 Get a L<File::KDBX::Cipher> capable of encrypting and decrypting the body of a database file.
1323 A key is required. This should be a raw encryption key made up of a fixed number of octets (depending on the
1324 cipher), not a L<File::KDBX::Key> or primitive.
1326 If not passed, the UUID comes from C<< $kdbx->headers->{cipher_id} >> and the encryption IV comes from
1327 C<< $kdbx->headers->{encryption_iv} >>.
1329 You generally don't need to call this directly
. The parser
and writer
use it to decrypt
and encrypt KDBX
1338 $args{uuid
} //= $self->headers->{+HEADER_CIPHER_ID
};
1339 $args{iv
} //= $self->headers->{+HEADER_ENCRYPTION_IV
};
1341 require File
::KDBX
::Cipher
;
1342 return File
::KDBX
::Cipher-
>new(%args);
1345 =method random_stream
1347 $cipher = $kdbx->random_stream;
1348 $cipher = $kdbx->random_stream(id
=> $stream_id, key
=> $key);
1350 Get a L
<File
::KDBX
::Cipher
::Stream
> for decrypting
and encrypting protected
values.
1352 If
not passed
, the ID
and encryption key comes from C
<< $kdbx->headers->{inner_random_stream_id
} >> and
1353 C
<< $kdbx->headers->{inner_random_stream_key
} >> (respectively
) for KDBX3 files
and from
1354 C
<< $kdbx->inner_headers->{inner_random_stream_key
} >> and
1355 C
<< $kdbx->inner_headers->{inner_random_stream_id
} >> (respectively
) for KDBX4 files
.
1357 You generally don
't need to call this directly. The parser and writer use it to scramble protected strings.
1365 $args{stream_id} //= delete $args{id} // $self->inner_random_stream_id;
1366 $args{key} //= $self->inner_random_stream_key;
1368 require File::KDBX::Cipher;
1369 File::KDBX::Cipher->new(%args);
1372 sub inner_random_stream_id {
1374 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID}
1375 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID} = shift if @_;
1376 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID}
1377 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID} //= do {
1378 my $version = $self->minimum_version;
1379 $version < KDBX_VERSION_4_0 ? STREAM_ID_SALSA20 : STREAM_ID_CHACHA20;
1383 sub inner_random_stream_key {
1386 # These are probably the same SvPV so erasing one will CoW, but erasing the second should do the
1388 erase \$self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY};
1389 erase \$self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY};
1390 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY}
1391 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY} = shift;
1393 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY}
1394 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY} //= random_bytes(64); # 32
1397 #########################################################################################
1400 # - Fixer tool. Can repair inconsistencies, including:
1401 # - Orphaned binaries... not really a thing anymore since we now distribute binaries amongst entries
1402 # - Unused custom icons (OFF, data loss)
1404 # - All data types are valid
1405 # - date times are correct
1407 # - All UUIDs refer to things that exist
1408 # - previous parent group
1410 # - last selected group
1411 # - last visible group
1412 # - Enforce history size limits (ON)
1413 # - Check headers/meta (ON)
1414 # - Duplicate deleted objects (ON)
1415 # - Duplicate window associations (OFF)
1416 # - Only one root group (ON)
1417 # - Header UUIDs match known ciphers/KDFs?
1420 #########################################################################################
1422 sub _handle_signal {
1428 'entry
.uuid
.changed
' => \&_update_entry_uuid,
1429 'group
.uuid
.changed
' => \&_update_group_uuid,
1431 my $handler = $handlers{$type} or return;
1432 $self->$handler($object, @_);
1435 sub _update_group_uuid {
1438 my $new_uuid = shift;
1439 my $old_uuid = shift // return;
1441 my $meta = $self->meta;
1442 $self->recycle_bin_uuid($new_uuid) if $old_uuid eq ($meta->{recycle_bin_uuid} // '');
1443 $self->entry_templates_group($new_uuid) if $old_uuid eq ($meta->{entry_templates_group} // '');
1444 $self->last_selected_group($new_uuid) if $old_uuid eq ($meta->{last_selected_group} // '');
1445 $self->last_top_visible_group($new_uuid) if $old_uuid eq ($meta->{last_top_visible_group} // '');
1447 for my $group (@{$self->all_groups}) {
1448 $group->last_top_visible_entry($new_uuid) if $old_uuid eq ($group->{last_top_visible_entry} // '');
1449 $group->previous_parent_group($new_uuid) if $old_uuid eq ($group->{previous_parent_group} // '');
1451 for my $entry (@{$self->all_entries}) {
1452 $entry->previous_parent_group($new_uuid) if $old_uuid eq ($entry->{previous_parent_group} // '');
1456 sub _update_entry_uuid {
1459 my $new_uuid = shift;
1460 my $old_uuid = shift // return;
1462 my $old_pretty = format_uuid($old_uuid);
1463 my $new_pretty = format_uuid($new_uuid);
1464 my $fieldref_match = qr/\{REF:([TUPANI])\@I:\Q$old_pretty\E\}/is;
1466 for my $entry (@{$self->all_entries}) {
1467 $entry->previous_parent_group($new_uuid) if $old_uuid eq ($entry->{previous_parent_group} // '');
1469 for my $string (values %{$entry->strings}) {
1470 next if !defined $string->{value} || $string->{value} !~ $fieldref_match;
1471 my $txn = $entry->begin_work;
1472 $string->{value} =~ s/$fieldref_match/{REF:$1\@I:$new_pretty}/g;
1478 #########################################################################################
1482 A text string associated with the database. Often unset.
1486 The UUID of a cipher used to encrypt the database when stored as a file.
1488 See L</File::KDBX::Cipher>.
1490 =attr compression_flags
1492 Configuration for whether or not and how the database gets compressed. See
1493 L<File::KDBX::Constants/":compression">.
1497 The master seed is a string of 32 random bytes that is used as salt in hashing the master key when loading
1498 and saving the database. If a challenge-response key is used in the master key, the master seed is also the
1501 The master seed I<should> be changed each time the database is saved to file.
1503 =attr transform_seed
1505 The transform seed is a string of 32 random bytes that is used in the key derivation function, either as the
1506 salt or the key (depending on the algorithm).
1508 The transform seed I<should> be changed each time the database is saved to file.
1510 =attr transform_rounds
1512 The number of rounds or iterations used in the key derivation function. Increasing this number makes loading
1513 and saving the database slower by design in order to make dictionary and brute force attacks more costly.
1517 The initialization vector used by the cipher.
1519 The encryption IV I<should> be changed each time the database is saved to file.
1521 =attr inner_random_stream_key
1523 The encryption key (possibly including the IV, depending on the cipher) used to encrypt the protected strings
1524 within the database.
1526 =attr stream_start_bytes
1528 A string of 32 random bytes written in the header and encrypted in the body. If the bytes do not match when
1529 loading a file then the wrong master key was used or the file is corrupt. Only KDBX 2 and KDBX 3 files use
1530 this. KDBX 4 files use an improved HMAC method to verify the master key and data integrity of the header and
1533 =attr inner_random_stream_id
1535 A number indicating the cipher algorithm used to encrypt the protected strings within the database, usually
1536 Salsa20 or ChaCha20. See L<File::KDBX::Constants/":random_stream">.
1538 =attr kdf_parameters
1540 A hash/dict of key-value pairs used to configure the key derivation function. This is the KDBX4+ way to
1541 configure the KDF, superceding L</transform_seed> and L</transform_rounds>.
1545 The name of the software used to generate the KDBX file.
1549 The header hash used to verify that the file header is not corrupt. (KDBX 2 - KDBX 3.1, removed KDBX 4.0)
1553 Name of the database.
1555 =attr database_name_changed
1557 Timestamp indicating when the database name was last changed.
1559 =attr database_description
1561 Description of the database
1563 =attr database_description_changed
1565 Timestamp indicating when the database description was last changed.
1567 =attr default_username
1569 When a new entry is created, the I<UserName> string will be populated with this value.
1571 =attr default_username_changed
1573 Timestamp indicating when the default username was last changed.
1575 =attr maintenance_history_days
1577 TODO... not really sure what this is. 😀
1581 A color associated with the database (in the form C<#ffffff> where "f" is a hexidecimal digit). Some agents
1582 use this to help users visually distinguish between different databases.
1584 =attr master_key_changed
1586 Timestamp indicating when the master key was last changed.
1588 =attr master_key_change_rec
1590 Number of days until the agent should prompt to recommend changing the master key.
1592 =attr master_key_change_force
1594 Number of days until the agent should prompt to force changing the master key.
1596 Note: This is purely advisory. It is up to the individual agent software to actually enforce it.
1597 C<File::KDBX> does NOT enforce it.
1599 =attr recycle_bin_enabled
1601 Boolean indicating whether removed groups and entries should go to a recycle bin or be immediately deleted.
1603 =attr recycle_bin_uuid
1605 The UUID of a group used to store thrown-away groups and entries.
1607 =attr recycle_bin_changed
1609 Timestamp indicating when the recycle bin was last changed.
1611 =attr entry_templates_group
1613 The UUID of a group containing template entries used when creating new entries.
1615 =attr entry_templates_group_changed
1617 Timestamp indicating when the entry templates group was last changed.
1619 =attr last_selected_group
1621 The UUID of the previously-selected group.
1623 =attr last_top_visible_group
1625 The UUID of the group visible at the top of the list.
1627 =attr history_max_items
1629 The maximum number of historical entries allowed to be saved for each entry.
1631 =attr history_max_size
1633 The maximum total size (in bytes) that each individual entry's history
is allowed to grow
.
1635 =attr settings_changed
1637 Timestamp indicating
when the database settings were
last updated
.
1641 Alias of the L
</memory_protection
> setting
for the I
<Title
> string
.
1643 =attr protect_username
1645 Alias of the L
</memory_protection
> setting
for the I
<UserName
> string
.
1647 =attr protect_password
1649 Alias of the L
</memory_protection
> setting
for the I
<Password
> string
.
1653 Alias of the L
</memory_protection
> setting
for the I
<URL
> string
.
1657 Alias of the L
</memory_protection
> setting
for the I
<Notes
> string
.
1661 #########################################################################################
1663 sub TO_JSON
{ +{%{$_[0]}} }
1668 =for Pod::Coverage STORABLE_freeze STORABLE_thaw TO_JSON
1674 my $kdbx = File::KDBX->new;
1676 my $group = $kdbx->add_group(
1677 name => 'Passwords',
1680 my $entry = $group->add_entry(
1682 password => 's3cr3t',
1685 $kdbx->dump_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1687 $kdbx = File::KDBX->load_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1689 for my $entry (@{ $kdbx->all_entries }) {
1690 say 'Entry: ', $entry->title;
1695 B<File::KDBX> provides everything you need to work with a KDBX database. A KDBX database is a hierarchical
1696 object database which is commonly used to store secret information securely. It was developed for the KeePass
1697 password safe. See L</"KDBX Introduction"> for more information about KDBX.
1699 This module lets you query entries, create new entries, delete entries and modify entries. The distribution
1700 also includes various parsers and generators for serializing and persisting databases.
1702 This design of this software was influenced by the L<KeePassXC|https://github.com/keepassxreboot/keepassxc>
1703 implementation of KeePass as well as the L<File::KeePass> module. B<File::KeePass> is an alternative module
1704 that works well in most cases but has a small backlog of bugs and security issues and also does not work with
1705 newer KDBX version 4 files. If you're coming here from the B<File::KeePass> world, you might be interested in
1706 L<File::KeePass::KDBX> that is a drop-in replacement for B<File::KeePass> that uses B<File::KDBX> for storage.
1708 =head2 KDBX Introduction
1710 A KDBX database consists of a hierarchical I<group> of I<entries>. Entries can contain zero or more key-value
1711 pairs of I<strings> and zero or more I<binaries> (i.e. octet strings). Groups, entries, strings and binaries:
1712 that's the KDBX vernacular. A small amount of metadata (timestamps, etc.) is associated with each entry, group
1713 and the database as a whole.
1715 You can think of a KDBX database kind of like a file system, where groups are directories, entries are files,
1716 and strings and binaries make up a file's contents.
1718 Databases are typically persisted as a encrypted, compressed files. They are usually accessed directly (i.e.
1719 not over a network). The primary focus of this type of database is data security. It is ideal for storing
1720 relatively small amounts of data (strings and binaries) that must remain secret except to such individuals as
1721 have the correct I<master key>. Even if the database file were to be "leaked" to the public Internet, it
1722 should be virtually impossible to crack with a strong key. See L</SECURITY> for an overview of security
1727 =head2 Create a new database
1729 my $kdbx = File::KDBX->new;
1731 my $group = $kdbx->add_group(name => 'Passwords);
1732 my $entry = $group->add_entry(
1733 title => 'WayneCorp',
1734 username => 'bwayne',
1735 password => 'iambatman',
1736 url => 'https://example.com/login'
1738 $entry->add_auto_type_window_association('WayneCorp - Mozilla Firefox', '{PASSWORD}{ENTER}');
1740 $kdbx->dump_file('mypasswords.kdbx', 'master password CHANGEME');
1742 =head2 Read an existing database
1744 my $kdbx = File::KDBX->load_file('mypasswords.kdbx', 'master password CHANGEME');
1747 for my $entry (@{ $kdbx->all_entries }) {
1748 say 'Found password for ', $entry->title, ':';
1749 say ' Username: ', $entry->username;
1750 say ' Password: ', $entry->password;
1753 =head2 Search for entries
1755 my @entries = $kdbx->find_entries({
1756 title => 'WayneCorp',
1759 See L</QUERY> for many more query examples.
1761 =head2 Search for entries by auto-type window association
1763 my @entry_key_sequences = $kdbx->find_entries_for_window('WayneCorp - Mozilla Firefox');
1764 for my $pair (@entry_key_sequences) {
1765 my ($entry, $key_sequence) = @$pair;
1766 say 'Entry title: ', $entry->title, ', key sequence: ', $key_sequence;
1771 Entry title: WayneCorp, key sequence: {PASSWORD}{ENTER}
1775 One of the biggest threats to your database security is how easily the encryption key can be brute-forced.
1776 Strong brute-force protection depends on a couple factors:
1779 * Using unguessable passwords, passphrases and key files.
1780 * Using a brute-force resistent key derivation function.
1782 The first factor is up to you. This module does not enforce strong master keys. It is up to you to pick or
1783 generate strong keys.
1785 The KDBX format allows for the key derivation function to be tuned. The idea is that you want each single
1786 brute-foce attempt to be expensive (in terms of time, CPU usage or memory usage), so that making a lot of
1787 attempts (which would be required if you have a strong master key) gets I<really> expensive.
1789 How expensive you want to make each attempt is up to you and can depend on the application.
1791 This and other KDBX-related security issues are covered here more in depth:
1792 L<https://keepass.info/help/base/security.html>
1794 Here are other security risks you should be thinking about:
1798 This distribution uses the excellent L<CryptX> and L<Crypt::Argon2> packages to handle all crypto-related
1799 functions. As such, a lot of the security depends on the quality of these dependencies. Fortunately these
1800 modules are maintained and appear to have good track records.
1802 The KDBX format has evolved over time to incorporate improved security practices and cryptographic functions.
1803 This package uses the following functions for authentication, hashing, encryption and random number
1809 * Argon2d & Argon2id
1814 * Salsa20 & ChaCha20
1817 At the time of this writing, I am not aware of any successful attacks against any of these functions. These
1818 are among the most-analyzed and widely-adopted crypto functions available.
1820 The KDBX format allows the body cipher and key derivation function to be configured. If a flaw is discovered
1821 in one of these functions, you can hopefully just switch to a better function without needing to update this
1822 software. A later software release may phase out the use of any functions which are no longer secure.
1824 =head2 Memory Protection
1826 It is not a good idea to keep secret information unencrypted in system memory for longer than is needed. The
1827 address space of your program can generally be read by a user with elevated privileges on the system. If your
1828 system is memory-constrained or goes into a hibernation mode, the contents of your address space could be
1829 written to a disk where it might be persisted for long time.
1831 There might be system-level things you can do to reduce your risk, like using swap encryption and limiting
1832 system access to your program's address space while your program is running.
1834 B<File::KDBX> helps minimize (but not eliminate) risk by keeping secrets encrypted in memory until accessed
1835 and zeroing out memory that holds secrets after they're no longer needed, but it's not a silver bullet.
1837 For one thing, the encryption key is stored in the same address space. If core is dumped, the encryption key
1838 is available to be found out. But at least there is the chance that the encryption key and the encrypted
1839 secrets won't both be paged out while memory-constrained.
1841 Another problem is that some perls (somewhat notoriously) copy around memory behind the scenes willy nilly,
1842 and it's difficult know when perl makes a copy of a secret in order to be able to zero it out later. It might
1843 be impossible. The good news is that perls with SvPV copy-on-write (enabled by default beginning with perl
1844 5.20) are much better in this regard. With COW, it's mostly possible to know what operations will cause perl
1845 to copy the memory of a scalar string, and the number of copies will be significantly reduced. There is a unit
1846 test named F<t/memory-protection.t> in this distribution that can be run on POSIX systems to determine how
1847 well B<File::KDBX> memory protection is working.
1849 Memory protection also depends on how your application handles secrets. If your app code is handling scalar
1850 strings with secret information, it's up to you to make sure its memory is zeroed out when no longer needed.
1851 L<File::KDBX::Util/erase> et al. provide some tools to help accomplish this. Or if you're not too concerned
1852 about the risks memory protection is meant to mitigate, then maybe don't worry about it. The security policy
1853 of B<File::KDBX> is to try hard to keep secrets protected while in memory so that your app might claim a high
1854 level of security, in case you care about that.
1856 There are some memory protection strategies that B<File::KDBX> does NOT use today but could in the future:
1858 Many systems allow programs to mark unswappable pages. Secret information should ideally be stored in such
1859 pages. You could potentially use L<mlockall(2)> (or equivalent for your system) in your own application to
1860 prevent the entire address space from being swapped.
1862 Some systems provide special syscalls for storing secrets in memory while keeping the encryption key outside
1863 of the program's address space, like C<CryptProtectMemory> for Windows. This could be a good option, though
1864 unfortunately not portable.
1868 Several methods take a I<query> as an argument (e.g. L</find_entries>). A query is just a subroutine that you
1869 can either write yourself or have generated for you based on either a simple expression or a declarative
1870 structure. It's easier to have your query generated, so I'll cover that first.
1872 =head2 Simple Expression
1874 A simple expression is mostly compatible with the KeePass 2 implementation
1875 L<described here|https://keepass.info/help/base/search.html#mode_se>.
1877 An expression is a string with one or more space-separated terms. Terms with spaces can be enclosed in double
1878 quotes. Terms are negated if they are prefixed with a minus sign. A record must match every term on at least
1879 one of the given fields.
1881 So a simple expression is something like what you might type into a search engine. You can generate a simple
1882 expression query using L<File::KDBX::Util/simple_expression_query> or by passing the simple expression as
1883 a B<string reference> to search methods like L</find_entries>.
1885 To search for all entries in a database with the word "canyon" appearing anywhere in the title:
1887 my @entries = $kdbx->find_entries([ \'canyon', qw(title) ]);
1889 Notice the first argument is a B<stringref>. This diambiguates a simple expression from other types of queries
1892 As mentioned, a simple expression can have multiple terms. This simple expression query matches any entry that
1893 has the words "red" B<and> "canyon" anywhere in the title:
1895 my @entries = $kdbx->find_entries([ \'red canyon', qw(title) ]);
1897 Each term in the simple expression must be found for an entry to match.
1899 To search for entries with "red" in the title but B<not> "canyon", just prepend "canyon" with a minus sign:
1901 my @entries = $kdbx->find_entries([ \'red -canyon', qw(title) ]);
1903 To search over multiple fields simultaneously, just list them. To search for entries with "grocery" in the
1904 title or notes but not "Foodland":
1906 my @entries = $kdbx->find_entries([ \'grocery -Foodland', qw(title notes) ]);
1908 The default operator is a case-insensitive regexp match, which is fine for searching text loosely. You can use
1909 just about any binary comparison operator that perl supports. To specify an operator, list it after the simple
1910 expression. For example, to search for any entry that has been used at least five times:
1912 my @entries = $kdbx->find_entries([ \5, '>=', qw(usage_count) ]);
1914 It helps to read it right-to-left, like "usage_count is >= 5".
1916 If you find the disambiguating structures to be confusing, you can also the L</find_entries_simple> method as
1917 a more intuitive alternative. The following example is equivalent to the previous:
1919 my @entries = $kdbx->find_entries_simple(5, '>=', qw(usage_count));
1921 =head2 Declarative Query
1923 Structuring a declarative query is similar to L<SQL::Abstract/"WHERE CLAUSES">, but you don't have to be
1924 familiar with that module. Just learn by examples.
1926 To search for all entries in a database titled "My Bank":
1928 my @entries = $kdbx->find_entries({ title => 'My Bank' });
1930 The query here is C<< { title => 'My Bank' } >>. A hashref can contain key-value pairs where the key is
1931 a attribute of the thing being searched for (in this case an entry) and the value is what you want the thing's
1932 attribute to be to consider it a match. In this case, the attribute we're using as our match criteria is
1933 L<File::KDBX::Entry/title>, a text field. If an entry has its title attribute equal to "My Bank", it's
1936 A hashref can contain multiple attributes. The search candidate will be a match if I<all> of the specified
1937 attributes are equal to their respective values. For example, to search for all entries with a particular URL
1940 my @entries = $kdbx->find_entries({
1941 url => 'https://example.com',
1945 To search for entries matching I<any> criteria, just change the hashref to an arrayref. To search for entries
1946 with a particular URL B<OR> a particular username:
1948 my @entries = $kdbx->find_entries([ # <-- square bracket
1949 url => 'https://example.com',
1953 You can user different operators to test different types of attributes. The L<File::KDBX::Entry/icon_id>
1954 attribute is a number, so we should use a number comparison operator. To find entries using the smartphone
1957 my @entries = $kdbx->find_entries({
1958 icon_id => { '==', ICON_SMARTPHONE },
1961 Note: L<File::KDBX::Constants/ICON_SMARTPHONE> is just a constant from L<File::KDBX::Constants>. It isn't
1962 special to this example or to queries generally. We could have just used a literal number.
1964 The important thing to notice here is how we wrapped the condition in another arrayref with a single key-pair
1965 where the key is the name of an operator and the value is the thing to match against. The supported operators
1969 * C<eq> - String equal
1970 * C<ne> - String not equal
1971 * C<lt> - String less than
1972 * C<gt> - String greater than
1973 * C<le> - String less than or equal
1974 * C<ge> - String greater than or equal
1975 * C<==> - Number equal
1976 * C<!=> - Number not equal
1977 * C<< < >> - Number less than
1978 * C<< > >>> - Number greater than
1979 * C<< <= >> - Number less than or equal
1980 * C<< >= >> - Number less than or equal
1981 * C<=~> - String match regular expression
1982 * C<!~> - String does not match regular expression
1983 * C<!> - Boolean false
1984 * C<!!> - Boolean true
1986 Other special operators:
1989 * C<-true> - Boolean true
1990 * C<-false> - Boolean false
1991 * C<-not> - Boolean false (alias for C<-false>)
1992 * C<-defined> - Is defined
1993 * C<-undef> - Is not d efined
1994 * C<-empty> - Is empty
1995 * C<-nonempty> - Is not empty
1996 * C<-or> - Logical or
1997 * C<-and> - Logical and
1999 Let's see another example using an explicit operator. To find all groups except one in particular (identified
2000 by its L<File::KDBX::Group/uuid>), we can use the C<ne> (string not equal) operator:
2002 my ($group, @other) = $kdbx->find_groups({
2004 'ne' => uuid('596f7520-6172-6520-7370-656369616c2e'),
2007 if (@other) { say "Problem: there can be only one!" }
2009 Note: L<File::KDBX::Util/uuid> is a little helper function to convert a UUID in its pretty form into octets.
2010 This helper function isn't special to this example or to queries generally. It could have been written with
2011 a literal such as C<"\x59\x6f\x75\x20\x61...">, but that's harder to read.
2013 Notice we searched for groups this time. Finding groups works exactly the same as it does for entries.
2015 Testing the truthiness of an attribute is a little bit different because it isn't a binary operation. To find
2016 all entries with the password quality check disabled:
2018 my @entries = $kdbx->find_entries({ '!' => 'quality_check' });
2020 This time the string after the operator is the attribute name rather than a value to compare the attribute
2021 against. To test that a boolean value is true, use the C<!!> operator (or C<-true> if C<!!> seems a little too
2022 weird for your taste):
2024 my @entries = $kdbx->find_entries({ '!!' => 'quality_check' });
2025 my @entries = $kdbx->find_entries({ -true => 'quality_check' });
2027 Yes, there is also a C<-false> and a C<-not> if you prefer one of those over C<!>. C<-false> and C<-not>
2028 (along with C<-true>) are also special in that you can use them to invert the logic of a subquery. These are
2029 logically equivalent:
2031 my @entries = $kdbx->find_entries([ -not => { title => 'My Bank' } ]);
2032 my @entries = $kdbx->find_entries({ title => { 'ne' => 'My Bank' } });
2034 These special operators become more useful when combined with two more special operators: C<-and> and C<-or>.
2035 With these, it is possible to construct more interesting queries with groups of logic. For example:
2037 my @entries = $kdbx->find_entries({
2038 title => { '=~', qr/bank/ },
2041 notes => { '=~', qr/business/ },
2042 icon_id => { '==', ICON_TRASHCAN_FULL },
2047 In English, find entries where the word "bank" appears anywhere in the title but also do not have either the
2048 word "business" in the notes or is using the full trashcan icon.
2050 =head2 Subroutine Query
2052 Lastly, as mentioned at the top, you can ignore all this and write your own subroutine. Your subroutine will
2053 be called once for each thing being searched over. The single argument is the search candidate. The subroutine
2054 should match the candidate against whatever criteria you want and return true if it matches. The C<find_*>
2055 methods collect all matching things and return them.
2057 For example, to find all entries in the database titled "My Bank":
2059 my @entries = $kdbx->find_entries(sub { shift->title eq 'My Bank' });
2060 # logically the same as this declarative structure:
2061 my @entries = $kdbx->find_entries({ title => 'My Bank' });
2062 # as well as this simple expression:
2063 my @entries = $kdbx->find_entries([ \'My Bank', 'eq', qw{title} ]);
2065 This is a trivial example, but of course your subroutine can be arbitrarily complex.
2067 All of these query mechanisms described in this section are just tools, each with its own set of limitations.
2068 If the tools are getting in your way, you can of course iterate over the contents of a database and implement
2069 your own query logic, like this:
2071 for my $entry (@{ $kdbx->all_entries }) {
2072 if (wanted($entry)) {
2073 do_something($entry);
2082 Errors in this package are constructed as L<File::KDBX::Error> objects and propagated using perl's built-in
2083 mechanisms. Fatal errors are propagated using L<functions/die> and non-fatal errors (a.k.a. warnings) are
2084 propagated using L<functions/warn> while adhering to perl's L<warnings> system. If you're already familiar
2085 with these mechanisms, you can skip this section.
2087 You can catch fatal errors using L<functions/eval> (or something like L<Try::Tiny>) and non-fatal errors using
2088 C<$SIG{__WARN__}> (see L<variables/%SIG>). Examples:
2090 use File::KDBX::Error qw(error);
2092 my $key = ''; # uh oh
2094 $kdbx->load_file('whatever.kdbx', $key);
2096 if (my $error = error($@)) {
2097 handle_missing_key($error) if $error->type eq 'key.missing';
2101 or using C<Try::Tiny>:
2104 $kdbx->load_file('whatever.kdbx', $key);
2110 Catching non-fatal errors:
2113 local $SIG{__WARN__} = sub { push @warnings, $_[0] };
2115 $kdbx->load_file('whatever.kdbx', $key);
2117 handle_warnings(@warnings) if @warnings;
2119 By default perl prints warnings to C<STDERR> if you don't catch them. If you don't want to catch them and also
2120 don't want them printed to C<STDERR>, you can suppress them lexically (perl v5.28 or higher required):
2123 no warnings 'File::KDBX';
2130 local $File::KDBX::WARNINGS = 0;
2134 or globally in your program:
2136 $File::KDBX::WARNINGS = 0;
2138 You cannot suppress fatal errors, and if you don't catch them your program will exit.
2142 This software will alter its behavior depending on the value of certain environment variables:
2145 * C<PERL_FILE_KDBX_XS> - Do not use L<File::KDBX::XS> if false (default: true)
2146 * C<PERL_ONLY> - Do not use L<File::KDBX::XS> if true (default: false)
2147 * C<NO_FORK> - Do not fork if true (default: false)
2151 Some features (e.g. parsing) require 64-bit perl. It should be possible and actually pretty easy to make it
2152 work using L<Math::BigInt>, but I need to build a 32-bit perl in order to test it and frankly I'm still
2153 figuring out how. I'm sure it's simple so I'll mark this one "TODO", but for now an exception will be thrown
2154 when trying to use such features with undersized IVs.
2158 L<File::KeePass> is a much older alternative. It's good but has a backlog of bugs and lacks support for newer
2175 =attr deleted_objects
2179 $value = $kdbx->$attr;
2180 $kdbx->$attr($value);
2182 Get and set attributes.