1 package File
::KDBX
::IO
::Crypt
;
2 # ABSTRACT: Encrypter/decrypter IO handle
9 use File
::KDBX
::Util
qw(:empty);
12 use parent
'File::KDBX::IO';
14 our $VERSION = '999.999'; # VERSION
15 our $BUFFER_SIZE = 16384;
20 $fh = File
::KDBX
::IO
::Crypt-
>new(%attributes);
21 $fh = File
::KDBX
::IO
::Crypt-
>new($fh, %attributes);
23 Construct a new crypto IO handle
.
29 my %args = @_ % 2 == 1 ? (fh
=> shift, @_) : @_;
30 my $self = $class->SUPER::new
;
31 $self->_fh($args{fh
}) or throw
'IO handle required';
32 $self->cipher($args{cipher
}) or throw
'Cipher required';
38 A L
<File
::KDBX
::Cipher
> instance to
do the actual encryption
or decryption
.
45 while (my ($attr, $default) = each %ATTRS) {
46 no strict
'refs'; ## no critic (ProhibitNoStrict)
49 *$self->{$attr} = shift if @_;
50 *$self->{$attr} //= (ref $default eq 'CODE') ? $default->($self) : $default;
57 $ENV{DEBUG_STREAM
} and print STDERR
"FILL\t$self\n";
58 my $cipher = $self->cipher or return;
60 $fh->read(my $buf = '', $BUFFER_SIZE);
61 if (0 < length($buf)) {
62 my $plaintext = eval { $cipher->decrypt($buf) };
64 $self->_set_error($err);
67 return $plaintext if 0 < length($plaintext);
71 my $plaintext = eval { $cipher->finish };
73 $self->_set_error($err);
81 my ($self, $buf, $fh) = @_;
83 $ENV{DEBUG_STREAM
} and print STDERR
"WRITE\t$self\n";
84 my $cipher = $self->cipher or return 0;
86 my $new_data = eval { $cipher->encrypt($buf) } || '';
88 $self->_set_error($err);
91 $self->_buffer_out_add($new_data) if nonempty
$new_data;
98 $ENV{DEBUG_STREAM
} and print STDERR
"POPPED\t$self\n";
99 return if $self->_mode ne 'w';
100 my $cipher = $self->cipher or return;
102 my $new_data = eval { $cipher->finish } || '';
104 $self->_set_error($err);
107 $self->_buffer_out_add($new_data) if nonempty
$new_data;
109 $self->cipher(undef);
114 my ($self, $fh) = @_;
116 $ENV{DEBUG_STREAM
} and print STDERR
"FLUSH\t$self\n";
117 return if $self->_mode ne 'w';
119 my $buffer = $self->_buffer_out;
121 my $read = shift @$buffer;
123 $fh->print($read) or return -1;
130 $ENV{DEBUG_STREAM
} and print STDERR
"err\t$self\n";
131 if (exists &Errno
::EPROTO
) {
134 elsif (exists &Errno
::EIO
) {
137 $self->cipher(undef);
138 $self->_error($ERROR = File
::KDBX
::Error-
>new(@_));
146 use File::KDBX::IO::Crypt;
147 use File::KDBX::Cipher;
149 my $cipher = File::KDBX::Cipher->new(...);
151 open(my $out_fh, '>:raw', 'ciphertext.bin');
152 $out_fh = File::KDBX::IO::Crypt->new($out_fh, cipher => $cipher);
154 print $out_fh $plaintext;
158 open(my $in_fh, '<:raw', 'ciphertext.bin');
159 $in_fh = File::KDBX::IO::Crypt->new($in_fh, cipher => $cipher);
161 my $plaintext = do { local $/; <$in_fh> );