2 use std
::io
::{Read, BufRead}
;
4 use anyhow
::{bail, Error}
;
6 use super::CryptConfig
;
8 pub struct CryptReader
<R
> {
10 small_read_buf
: Vec
<u8>,
12 crypter
: openssl
::symm
::Crypter
,
16 impl <R
: BufRead
> CryptReader
<R
> {
18 pub fn new(reader
: R
, iv
: [u8; 16], tag
: [u8; 16], config
: Arc
<CryptConfig
>) -> Result
<Self, Error
> {
19 let block_size
= config
.cipher().block_size(); // Note: block size is normally 1 byte for stream ciphers
20 if block_size
.count_ones() != 1 || block_size
> 512 {
21 bail
!("unexpected Cipher block size {}", block_size
);
23 let mut crypter
= config
.data_crypter(&iv
, openssl
::symm
::Mode
::Decrypt
)?
;
24 crypter
.set_tag(&tag
)?
;
26 Ok(Self { reader, crypter, block_size, finalized: false, small_read_buf: Vec::new() }
)
29 pub fn finish(self) -> Result
<R
, Error
> {
31 bail
!("CryptReader not successfully finalized.");
37 impl <R
: BufRead
> Read
for CryptReader
<R
> {
39 fn read(&mut self, buf
: &mut [u8]) -> Result
<usize, std
::io
::Error
> {
40 if !self.small_read_buf
.is_empty() {
41 let max
= if self.small_read_buf
.len() > buf
.len() { buf.len() }
else { self.small_read_buf.len() }
;
42 let rest
= self.small_read_buf
.split_off(max
);
43 buf
[..max
].copy_from_slice(&self.small_read_buf
);
44 self.small_read_buf
= rest
;
48 let data
= self.reader
.fill_buf()?
;
50 // handle small read buffers
51 if buf
.len() <= 2*self.block_size
{
52 let mut outbuf
= [0u8; 1024];
54 let count
= if data
.is_empty() { // EOF
55 let written
= self.crypter
.finalize(&mut outbuf
)?
;
56 self.finalized
= true;
59 let mut read_size
= outbuf
.len() - self.block_size
;
60 if read_size
> data
.len() {
61 read_size
= data
.len();
63 let written
= self.crypter
.update(&data
[..read_size
], &mut outbuf
)?
;
64 self.reader
.consume(read_size
);
68 if count
> buf
.len() {
69 buf
.copy_from_slice(&outbuf
[..buf
.len()]);
70 self.small_read_buf
= outbuf
[buf
.len()..count
].to_vec();
73 buf
[..count
].copy_from_slice(&outbuf
[..count
]);
76 } else if data
.is_empty() { // EOF
77 let rest
= self.crypter
.finalize(buf
)?
;
78 self.finalized
= true;
81 let mut read_size
= buf
.len() - self.block_size
;
82 if read_size
> data
.len() {
83 read_size
= data
.len();
85 let count
= self.crypter
.update(&data
[..read_size
], buf
)?
;
86 self.reader
.consume(read_size
);