$kdbx->add_entry($entry, %options);
$kdbx->add_entry(%entry_attributes, %options);
-Add a entry to a database. This is equivalent to identifying a parent group and calling
+Add an entry to a database. This is equivalent to identifying a parent group and calling
L<File::KDBX::Group/add_entry> on the parent group, forwarding the arguments. Available options:
=for :list
sub lock {
my $self = shift;
- $self->_safe and return $self;
-
+ # Find things to lock:
my @strings;
-
$self->entries(history => 1)->each(sub {
- push @strings, grep { $_->{protect} } values %{$_->strings}, values %{$_->binaries};
+ my $strings = $_->strings;
+ for my $string_key (keys %$strings) {
+ my $string = $strings->{$string_key};
+ push @strings, $string if $string->{protect} // $self->memory_protection($string_key);
+ }
+ push @strings, grep { $_->{protect} } values %{$_->binaries};
});
+ return $self if !@strings; # nothing to do
- $self->_safe(File::KDBX::Safe->new(\@strings));
-
+ if (my $safe = $self->_safe) {
+ $safe->add(\@strings);
+ }
+ else {
+ $self->_safe(File::KDBX::Safe->new(\@strings));
+ }
return $self;
}
limit: -1)
* C<max_size> - Maximum total size (in bytes) of historical entries to keep (default: value of
L</history_max_size>, no limit: -1)
-* C<max_age> - Maximum age (in days) of historical entries to keep (default: 365, no limit: -1)
+* C<max_age> - Maximum age (in days) of historical entries to keep (default: value of
+ L</maintenance_history_days>, no limit: -1)
=cut
* L</transform_seed>
Randomizing these values has no effect on a loaded database. These are only used when a database is dumped.
-You normally do not need to call this method explicitly because the dumper does it explicitly by default.
+You normally do not need to call this method explicitly because the dumper does it for you by default.
=cut
my %args = @_ % 2 == 1 ? (params => shift, @_) : @_;
my $params = $args{params};
- my $compat = $args{compatible} // 1;
$params //= $self->kdf_parameters;
$params = {%{$params || {}}};
sub transform_seed {
my $self = shift;
+ my $param = KDF_PARAM_AES_SEED; # Short cut: Argon2 uses the same parameter name ("S")
$self->headers->{+HEADER_TRANSFORM_SEED} =
- $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} = shift if @_;
+ $self->headers->{+HEADER_KDF_PARAMETERS}{$param} = shift if @_;
$self->headers->{+HEADER_TRANSFORM_SEED} =
- $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} //= random_bytes(32);
+ $self->headers->{+HEADER_KDF_PARAMETERS}{$param} //= random_bytes(32);
}
sub transform_rounds {
my $self = shift;
+ require File::KDBX::KDF;
+ my $info = $File::KDBX::KDF::ROUNDS_INFO{$self->kdf_parameters->{+KDF_PARAM_UUID} // ''} //
+ $File::KDBX::KDF::DEFAULT_ROUNDS_INFO;
$self->headers->{+HEADER_TRANSFORM_ROUNDS} =
- $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} = shift if @_;
+ $self->headers->{+HEADER_KDF_PARAMETERS}{$info->{p}} = shift if @_;
$self->headers->{+HEADER_TRANSFORM_ROUNDS} =
- $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} //= 100_000;
+ $self->headers->{+HEADER_KDF_PARAMETERS}{$info->{p}} //= $info->{d};
}
=method cipher
=attr comment
-A text string associated with the database. Often unset.
+A text string associated with the database stored unencrypted in the file header. Often unset.
=attr cipher_id
=attr transform_rounds
The number of rounds or iterations used in the key derivation function. Increasing this number makes loading
-and saving the database slower by design in order to make dictionary and brute force attacks more costly.
+and saving the database slower in order to make dictionary and brute force attacks more costly.
=attr encryption_iv
generate strong keys.
The KDBX format allows for the key derivation function to be tuned. The idea is that you want each single
-brute-foce attempt to be expensive (in terms of time, CPU usage or memory usage), so that making a lot of
+brute-force attempt to be expensive (in terms of time, CPU usage or memory usage), so that making a lot of
attempts (which would be required if you have a strong master key) gets I<really> expensive.
How expensive you want to make each attempt is up to you and can depend on the application.
It helps to read it right-to-left, like "usage_count is greater than or equal to 5".
-If you find the disambiguating structures to be distracting or confusing, you can also the
+If you find the disambiguating structures to be distracting or confusing, you can also use the
L<File::KDBX::Util/simple_expression_query> function as a more intuitive alternative. The following example is
equivalent to the previous:
Note: L<File::KDBX::Constants/ICON_SMARTPHONE> is just a constant from L<File::KDBX::Constants>. It isn't
special to this example or to queries generally. We could have just used a literal number.
-The important thing to notice here is how we wrapped the condition in another arrayref with a single key-value
+The important thing to notice here is how we wrapped the condition in another hashref with a single key-value
pair where the key is the name of an operator and the value is the thing to match against. The supported
operators are: