1 use anyhow
::{bail, Error}
;
3 use std
::io
::{Read, BufRead}
;
5 use super::CryptConfig
;
7 pub struct CryptReader
<R
> {
9 small_read_buf
: Vec
<u8>,
11 crypter
: openssl
::symm
::Crypter
,
15 impl <R
: BufRead
> CryptReader
<R
> {
17 pub fn new(reader
: R
, iv
: [u8; 16], tag
: [u8; 16], config
: Arc
<CryptConfig
>) -> Result
<Self, Error
> {
18 let block_size
= config
.cipher().block_size(); // Note: block size is normally 1 byte for stream ciphers
19 if block_size
.count_ones() != 1 || block_size
> 512 {
20 bail
!("unexpected Cipher block size {}", block_size
);
22 let mut crypter
= config
.data_crypter(&iv
, openssl
::symm
::Mode
::Decrypt
)?
;
23 crypter
.set_tag(&tag
)?
;
25 Ok(Self { reader, crypter, block_size, finalized: false, small_read_buf: Vec::new() }
)
28 pub fn finish(self) -> Result
<R
, Error
> {
30 bail
!("CryptReader not successfully finalized.");
36 impl <R
: BufRead
> Read
for CryptReader
<R
> {
38 fn read(&mut self, buf
: &mut [u8]) -> Result
<usize, std
::io
::Error
> {
39 if self.small_read_buf
.len() > 0 {
40 let max
= if self.small_read_buf
.len() > buf
.len() { buf.len() }
else { self.small_read_buf.len() }
;
41 let rest
= self.small_read_buf
.split_off(max
);
42 buf
[..max
].copy_from_slice(&self.small_read_buf
);
43 self.small_read_buf
= rest
;
47 let data
= self.reader
.fill_buf()?
;
49 // handle small read buffers
50 if buf
.len() <= 2*self.block_size
{
51 let mut outbuf
= [0u8; 1024];
53 let count
= if data
.len() == 0 { // EOF
54 let written
= self.crypter
.finalize(&mut outbuf
)?
;
55 self.finalized
= true;
58 let mut read_size
= outbuf
.len() - self.block_size
;
59 if read_size
> data
.len() {
60 read_size
= data
.len();
62 let written
= self.crypter
.update(&data
[..read_size
], &mut outbuf
)?
;
63 self.reader
.consume(read_size
);
67 if count
> buf
.len() {
68 buf
.copy_from_slice(&outbuf
[..buf
.len()]);
69 self.small_read_buf
= outbuf
[buf
.len()..count
].to_vec();
72 buf
[..count
].copy_from_slice(&outbuf
[..count
]);
75 } else if data
.len() == 0 { // EOF
76 let rest
= self.crypter
.finalize(buf
)?
;
77 self.finalized
= true;
80 let mut read_size
= buf
.len() - self.block_size
;
81 if read_size
> data
.len() {
82 read_size
= data
.len();
84 let count
= self.crypter
.update(&data
[..read_size
], buf
)?
;
85 self.reader
.consume(read_size
);