X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=lib%2FFile%2FKDBX%2FCipher%2FStream.pm;h=367619acbd1548bc0055420e2e251b5f1d081247;hb=37b09e0f2832514b33de4499a83f22d5ffe7c0a3;hp=1b9aecadf1bfcd5404d08e511473ebc381041b65;hpb=f63182fc62b25269b1c38588dca2b3535ed1a1a2;p=chaz%2Fp5-File-KDBX diff --git a/lib/File/KDBX/Cipher/Stream.pm b/lib/File/KDBX/Cipher/Stream.pm index 1b9aeca..367619a 100644 --- a/lib/File/KDBX/Cipher/Stream.pm +++ b/lib/File/KDBX/Cipher/Stream.pm @@ -7,13 +7,35 @@ use strict; use Crypt::Digest qw(digest_data); use File::KDBX::Constants qw(:cipher :random_stream); use File::KDBX::Error; +use File::KDBX::Util qw(:class); +use Scalar::Util qw(blessed); use Module::Load; use namespace::clean; -use parent 'File::KDBX::Cipher'; +extends 'File::KDBX::Cipher'; our $VERSION = '999.999'; # VERSION +=attr counter + + $counter = $cipher->counter; + +Get the initial counter / block count into the keystream. + +=attr offset + + $offset = $cipher->offset; + +Get the initial byte offset into the keystream. This has precedence over L if both are set. + +=cut + +has 'counter', is => 'ro', default => 0; +has 'offset', is => 'ro'; +sub key_size { { Salsa20 => 32, ChaCha => 32 }->{$_[0]->{algorithm} || ''} // 0 } +sub iv_size { { Salsa20 => 8, ChaCha => 12 }->{$_[0]->{algorithm} || ''} // -1 } +sub block_size { 1 } + sub init { my $self = shift; my %args = @_; @@ -42,27 +64,49 @@ sub init { return $self; } +=method crypt + + $ciphertext = $cipher->crypt($plaintext); + $plaintext = $cipher->crypt($ciphertext); + +Encrypt or decrypt some data. These ciphers are symmetric, so encryption and decryption are the same +operation. This method is an alias for both L and L. + +=cut + sub crypt { my $self = shift; my $stream = $self->_stream; return join('', map { $stream->crypt(ref $_ ? $$_ : $_) } grep { defined } @_); } +=method keystream + + $stream = $cipher->keystream; + +Access the keystream. + +=cut + sub keystream { my $self = shift; return $self->_stream->keystream(@_); } +=method dup + + $cipher_copy = $cipher->dup(%attributes); + +Get a copy of an existing cipher with the counter reset, optionally applying new attributes. + +=cut + sub dup { - my $self = shift; - my $dup = File::KDBX::Cipher->new( - stream_id => $self->stream_id, - key => $self->key, - @_, - ); - $dup->{key} = $self->key; - $dup->{iv} = $self->iv; - # FIXME - probably turn this into a proper clone method + my $self = shift; + my $class = blessed($self); + + my $dup = bless {%$self, @_}, $class; + delete $dup->{stream}; return $dup; } @@ -86,7 +130,7 @@ sub _stream { if (my $err = $@) { throw 'Failed to initialize stream cipher library', error => $err, - algorithm => $self->algorithm, + algorithm => $self->{algorithm}, key_length => length($self->key), iv_length => length($self->iv), iv => unpack('H*', $self->iv), @@ -101,20 +145,6 @@ sub decrypt { goto &crypt } sub finish { delete $_[0]->{stream}; '' } -sub counter { $_[0]->{counter} // 0 } -sub offset { $_[0]->{offset} } - -=attr algorithm - -Get the stream cipher algorithm. Can be one of C and C. - -=cut - -sub algorithm { $_[0]->{algorithm} or throw 'Stream cipher algorithm is not set' } -sub key_size { { Salsa20 => 32, ChaCha => 32 }->{$_[0]->{algorithm} || ''} // 0 } -sub iv_size { { Salsa20 => 8, ChaCha => 12 }->{$_[0]->{algorithm} || ''} // -1 } -sub block_size { 1 } - 1; __END__