X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fp5-File-KDBX;a=blobdiff_plain;f=lib%2FFile%2FKDBX%2FKey.pm;h=b44faca9183c117e95cd70457ba03127a903485b;hp=e7ac888d85b051304038a56daaca94619d91c7c6;hb=63d73bf382edfb0089b36a45193fc2835cb58b6d;hpb=f63182fc62b25269b1c38588dca2b3535ed1a1a2 diff --git a/lib/File/KDBX/Key.pm b/lib/File/KDBX/Key.pm index e7ac888..b44faca 100644 --- a/lib/File/KDBX/Key.pm +++ b/lib/File/KDBX/Key.pm @@ -8,14 +8,15 @@ use Devel::GlobalDestruction; use File::KDBX::Error; use File::KDBX::Safe; use File::KDBX::Util qw(erase); +use Hash::Util::FieldHash qw(fieldhashes); use Module::Load; use Ref::Util qw(is_arrayref is_coderef is_hashref is_ref is_scalarref); -use Scalar::Util qw(blessed openhandle refaddr); +use Scalar::Util qw(blessed openhandle); use namespace::clean; our $VERSION = '999.999'; # VERSION -my %SAFE; +fieldhashes \my %SAFE; =method new @@ -55,7 +56,10 @@ sub new { return $self; } -sub DESTROY { !in_global_destruction and do { $_[0]->_clear_raw_key; erase \$_[0]->{primitive} } } +sub DESTROY { + local ($., $@, $!, $^E, $?); + !in_global_destruction and do { $_[0]->_clear_raw_key; eval { erase \$_[0]->{primitive} } } +} =method init @@ -128,7 +132,7 @@ Get the raw encryption key. This is calculated based on the primitive(s). The C< challenge-response type keys and is ignored by other types. B The raw key is sensitive information and so is memory-protected while not being accessed. If you -access it, you should L it when you're done. +access it, you should memzero or L it when you're done. =cut @@ -156,7 +160,8 @@ sub _clear_raw_key { $key = $key->hide; -Encrypt the raw key for L. Returns itself to allow method chaining. +Put the raw key in L. Does nothing if the raw key is already +in memory protection. Returns itself to allow method chaining. =cut @@ -170,9 +175,8 @@ sub hide { $key = $key->show; -Decrypt the raw key so it can be accessed. Returns itself to allow method chaining. - -You normally don't need to call this because L calls this implicitly. +Bring the raw key out of memory protection. Does nothing if the raw key is already out of memory protection. +Returns itself to allow method chaining. =cut @@ -183,17 +187,18 @@ sub show { return $self; } -sub is_hidden { !!$SAFE{refaddr($_[0])} } +=method is_hidden + + $bool = $key->is_hidden; + +Get whether or not the key's raw secret is currently in memory protection. + +=cut -# sub show_scoped { -# my $self = shift; -# require Scope::Guard; -# $self- -# return -# } +sub is_hidden { !!$SAFE{$_[0]} } -sub _safe { $SAFE{refaddr($_[0])} } -sub _new_safe { $SAFE{refaddr($_[0])} = File::KDBX::Safe->new } +sub _safe { $SAFE{$_[0]} } +sub _new_safe { $SAFE{$_[0]} = File::KDBX::Safe->new } 1; __END__ @@ -209,7 +214,7 @@ There are several different types of keys, each implemented as a subclass: =for :list * L - Password or passphrase, knowledge of a string of characters -* L - Possession of a file ("key file") with a secret. +* L - Possession of a file ("key file") with a secret * L - Possession of a device that responds correctly when challenged * L - Possession of a YubiKey hardware device (a type of challenge-response) * L - One or more keys combined as one @@ -222,11 +227,11 @@ password key by itself. (Of course it's much better to not have any weak compone B Most KeePass implementations are limited in the types and numbers of keys they support. B keys are pretty much universally supported. B keys are pretty well-supported. Many do not support challenge-response keys. If you are concerned about compatibility, you should stick with one of these -configurations: +well-supported configurations: =for :list * One password * One key file -* One password and one key file +* Composite of one password and one key file =cut