]>
Dogcows Code - chaz/p5-File-KDBX/blob - lib/File/KDBX/Key.pm
1 package File
::KDBX
::Key
;
2 # ABSTRACT: A credential that can protect a KDBX file
7 use Devel
::GlobalDestruction
;
10 use File
::KDBX
::Util
qw(erase);
11 use Hash
::Util
::FieldHash
qw(fieldhashes);
13 use Ref
::Util
qw(is_arrayref is_coderef is_hashref is_ref is_scalarref);
14 use Scalar
::Util
qw(blessed openhandle);
17 our $VERSION = '0.900'; # VERSION
19 fieldhashes \
my %SAFE;
24 my %args = @_ % 2 == 1 ? (primitive
=> shift, @_) : @_;
26 my $primitive = $args{primitive
};
27 delete $args{primitive
} if !$args{keep_primitive
};
28 return $primitive->hide if blessed
$primitive && $primitive->isa($class);
30 my $self = bless \
%args, $class;
31 return $self->init($primitive) if defined $primitive;
36 local ($., $@, $!, $^E, $?);
37 !in_global_destruction
and do { $_[0]->_clear_raw_key; eval { erase \
$_[0]->{primitive
} } }
43 my $primitive = shift // throw
'Missing key primitive';
47 if (is_arrayref
($primitive)) {
48 $pkg = __PACKAGE__
.'::Composite';
50 elsif (is_scalarref
($primitive) || openhandle
($primitive)) {
51 $pkg = __PACKAGE__
.'::File';
53 elsif (is_coderef
($primitive)) {
54 $pkg = __PACKAGE__
.'::ChallengeResponse';
56 elsif (!is_ref
($primitive)) {
57 $pkg = __PACKAGE__
.'::Password';
59 elsif (is_hashref
($primitive) && defined $primitive->{composite
}) {
60 $pkg = __PACKAGE__
.'::Composite';
61 $primitive = $primitive->{composite
};
63 elsif (is_hashref
($primitive) && defined $primitive->{password
}) {
64 $pkg = __PACKAGE__
.'::Password';
65 $primitive = $primitive->{password
};
67 elsif (is_hashref
($primitive) && defined $primitive->{file
}) {
68 $pkg = __PACKAGE__
.'::File';
69 $primitive = $primitive->{file
};
71 elsif (is_hashref
($primitive) && defined $primitive->{responder
}) {
72 $pkg = __PACKAGE__
.'::ChallengeResponse';
73 $primitive = $primitive->{responder
};
76 throw
'Invalid key primitive', primitive
=> $primitive;
81 return $self->init($primitive);
90 return $self->{raw_key
} if !$self->is_hidden;
91 return $self->_safe->peek(\
$self->{raw_key
});
96 $self->_clear_raw_key;
97 $self->{raw_key
} = shift; # after clear
98 $self->_new_safe->add(\
$self->{raw_key
}); # auto-hide
103 my $safe = $self->_safe;
104 $safe->clear if $safe;
105 erase \
$self->{raw_key
};
111 $self->_new_safe->add(\
$self->{raw_key
}) if defined $self->{raw_key
};
118 my $safe = $self->_safe;
119 $safe->unlock if $safe;
124 sub is_hidden
{ !!$SAFE{$_[0]} }
126 sub _safe
{ $SAFE{$_[0]} }
127 sub _new_safe
{ $SAFE{$_[0]} = File
::KDBX
::Safe-
>new }
139 File::KDBX::Key - A credential that can protect a KDBX file
147 A master key is one or more credentials that can protect a KDBX database. When you encrypt a database with
148 a master key, you will need the master key to decrypt it. B<Keep your master key safe!> If someone gains
149 access to your master key, they can open your database. If you forget or lose any part of your master key, all
150 data in the database is lost.
152 There are several different types of keys, each implemented as a subclass:
158 L<File::KDBX::Key::Password> - Password or passphrase, knowledge of a string of characters
162 L<File::KDBX::Key::File> - Possession of a file ("key file") with a secret
166 L<File::KDBX::Key::ChallengeResponse> - Possession of a device that responds correctly when challenged
170 L<File::KDBX::Key::YubiKey> - Possession of a YubiKey hardware device (a type of challenge-response)
174 L<File::KDBX::Key::Composite> - One or more keys combined as one
178 A good master key is produced from a high amount of "entropy" (unpredictability). The more entropy the better.
179 Combining multiple keys into a B<Composite> key combines the entropy of each individual key. For example, if
180 you have a weak password and you combine it with other keys, the composite key is stronger than the weak
181 password key by itself. (Of course it's much better to not have any weak components of your master key.)
183 B<COMPATIBILITY NOTE:> Most KeePass implementations are limited in the types and numbers of keys they support.
184 B<Password> keys are pretty much universally supported. B<File> keys are pretty well-supported. Many do not
185 support challenge-response keys. If you are concerned about compatibility, you should stick with one of these
186 well-supported configurations:
200 Composite of one password and one key file
208 $key = File::KDBX::Key->new({ password => $password });
209 $key = File::KDBX::Key->new($password);
211 $key = File::KDBX::Key->new({ file => $filepath });
212 $key = File::KDBX::Key->new(\$file);
213 $key = File::KDBX::Key->new(\*FILE);
215 $key = File::KDBX::Key->new({ composite => [...] });
216 $key = File::KDBX::Key->new([...]); # composite key
218 $key = File::KDBX::Key->new({ responder => \&responder });
219 $key = File::KDBX::Key->new(\&responder); # challenge-response key
223 The primitive used to construct the key is not saved but is immediately converted to a raw encryption key (see
226 A L<File::KDBX::Key::Composite> is somewhat special in that it does retain a reference to its component keys,
227 and its raw key is calculated from its components on demand.
231 $key = $key->init($primitive);
233 Initialize a L<File::KDBX::Key> with a new primitive. Returns itself to allow method chaining.
239 Reload a key by re-reading the key source and recalculating the raw key. Returns itself to allow method
244 $raw_key = $key->raw_key;
245 $raw_key = $key->raw_key($challenge);
247 Get the raw encryption key. This is calculated based on the primitive(s). The C<$challenge> argument is for
248 challenge-response type keys and is ignored by other types.
250 B<NOTE:> The raw key is sensitive information and so is memory-protected while not being accessed. If you
251 access it, you should memzero or L<File::KDBX::Util/erase> it when you're done.
257 Put the raw key in L<memory protection|File::KDBX/"Memory Protection">. Does nothing if the raw key is already
258 in memory protection. Returns itself to allow method chaining.
264 Bring the raw key out of memory protection. Does nothing if the raw key is already out of memory protection.
265 Returns itself to allow method chaining.
269 $bool = $key->is_hidden;
271 Get whether or not the key's raw secret is currently in memory protection.
275 Please report any bugs or feature requests on the bugtracker website
276 L<https://github.com/chazmcgarvey/File-KDBX/issues>
278 When submitting a bug or request, please include a test-file or a
279 patch to an existing test-file that illustrates the bug or desired
284 Charles McGarvey <ccm@cpan.org>
286 =head1 COPYRIGHT AND LICENSE
288 This software is copyright (c) 2022 by Charles McGarvey.
290 This is free software; you can redistribute it and/or modify it under
291 the same terms as the Perl 5 programming language system itself.
This page took 0.050142 seconds and 4 git commands to generate.