3 use std
::io
::{Read, BufReader}
;
4 use proxmox
::tools
::io
::ReadExt
;
8 enum BlobReaderState
<R
: Read
> {
9 Uncompressed { expected_crc: u32, csum_reader: ChecksumReader<R> }
,
10 Compressed { expected_crc: u32, decompr: zstd::stream::read::Decoder<BufReader<ChecksumReader<R>>> }
,
11 Signed { expected_crc: u32, expected_hmac: [u8; 32], csum_reader: ChecksumReader<R> }
,
12 SignedCompressed { expected_crc: u32, expected_hmac: [u8; 32], decompr: zstd::stream::read::Decoder<BufReader<ChecksumReader<R>>> }
,
13 Encrypted { expected_crc: u32, decrypt_reader: CryptReader<BufReader<ChecksumReader<R>>> }
,
14 EncryptedCompressed { expected_crc: u32, decompr: zstd::stream::read::Decoder<BufReader<CryptReader<BufReader<ChecksumReader<R>>>>> }
,
18 pub struct DataBlobReader
<R
: Read
> {
19 state
: BlobReaderState
<R
>,
22 impl <R
: Read
> DataBlobReader
<R
> {
24 pub fn new(mut reader
: R
, config
: Option
<Arc
<CryptConfig
>>) -> Result
<Self, Error
> {
26 let head
: DataBlobHeader
= unsafe { reader.read_le_value()? }
;
28 UNCOMPRESSED_BLOB_MAGIC_1_0
=> {
29 let expected_crc
= u32::from_le_bytes(head
.crc
);
30 let csum_reader
= ChecksumReader
::new(reader
, None
);
31 Ok(Self { state: BlobReaderState::Uncompressed { expected_crc, csum_reader }
})
33 COMPRESSED_BLOB_MAGIC_1_0
=> {
34 let expected_crc
= u32::from_le_bytes(head
.crc
);
35 let csum_reader
= ChecksumReader
::new(reader
, None
);
37 let decompr
= zstd
::stream
::read
::Decoder
::new(csum_reader
)?
;
38 Ok(Self { state: BlobReaderState::Compressed { expected_crc, decompr }
})
40 AUTHENTICATED_BLOB_MAGIC_1_0
=> {
41 let expected_crc
= u32::from_le_bytes(head
.crc
);
42 let mut expected_hmac
= [0u8; 32];
43 reader
.read_exact(&mut expected_hmac
)?
;
44 let csum_reader
= ChecksumReader
::new(reader
, config
);
45 Ok(Self { state: BlobReaderState::Signed { expected_crc, expected_hmac, csum_reader }
})
47 AUTH_COMPR_BLOB_MAGIC_1_0
=> {
48 let expected_crc
= u32::from_le_bytes(head
.crc
);
49 let mut expected_hmac
= [0u8; 32];
50 reader
.read_exact(&mut expected_hmac
)?
;
51 let csum_reader
= ChecksumReader
::new(reader
, config
);
53 let decompr
= zstd
::stream
::read
::Decoder
::new(csum_reader
)?
;
54 Ok(Self { state: BlobReaderState::SignedCompressed { expected_crc, expected_hmac, decompr }
})
56 ENCRYPTED_BLOB_MAGIC_1_0
=> {
57 let expected_crc
= u32::from_le_bytes(head
.crc
);
58 let mut iv
= [0u8; 16];
59 let mut expected_tag
= [0u8; 16];
60 reader
.read_exact(&mut iv
)?
;
61 reader
.read_exact(&mut expected_tag
)?
;
62 let csum_reader
= ChecksumReader
::new(reader
, None
);
63 let decrypt_reader
= CryptReader
::new(BufReader
::with_capacity(64*1024, csum_reader
), iv
, expected_tag
, config
.unwrap())?
;
64 Ok(Self { state: BlobReaderState::Encrypted { expected_crc, decrypt_reader }
})
66 ENCR_COMPR_BLOB_MAGIC_1_0
=> {
67 let expected_crc
= u32::from_le_bytes(head
.crc
);
68 let mut iv
= [0u8; 16];
69 let mut expected_tag
= [0u8; 16];
70 reader
.read_exact(&mut iv
)?
;
71 reader
.read_exact(&mut expected_tag
)?
;
72 let csum_reader
= ChecksumReader
::new(reader
, None
);
73 let decrypt_reader
= CryptReader
::new(BufReader
::with_capacity(64*1024, csum_reader
), iv
, expected_tag
, config
.unwrap())?
;
74 let decompr
= zstd
::stream
::read
::Decoder
::new(decrypt_reader
)?
;
75 Ok(Self { state: BlobReaderState::EncryptedCompressed { expected_crc, decompr }
})
77 _
=> bail
!("got wrong magic number {:?}", head
.magic
)
81 pub fn finish(self) -> Result
<R
, Error
> {
83 BlobReaderState
::Uncompressed { csum_reader, expected_crc }
=> {
84 let (reader
, crc
, _
) = csum_reader
.finish()?
;
85 if crc
!= expected_crc
{
86 bail
!("blob crc check failed");
90 BlobReaderState
::Compressed { expected_crc, decompr }
=> {
91 let csum_reader
= decompr
.finish().into_inner();
92 let (reader
, crc
, _
) = csum_reader
.finish()?
;
93 if crc
!= expected_crc
{
94 bail
!("blob crc check failed");
98 BlobReaderState
::Signed { csum_reader, expected_crc, expected_hmac }
=> {
99 let (reader
, crc
, hmac
) = csum_reader
.finish()?
;
100 if crc
!= expected_crc
{
101 bail
!("blob crc check failed");
103 if let Some(hmac
) = hmac
{
104 if hmac
!= expected_hmac
{
105 bail
!("blob signature check failed");
110 BlobReaderState
::SignedCompressed { expected_crc, expected_hmac, decompr }
=> {
111 let csum_reader
= decompr
.finish().into_inner();
112 let (reader
, crc
, hmac
) = csum_reader
.finish()?
;
113 if crc
!= expected_crc
{
114 bail
!("blob crc check failed");
116 if let Some(hmac
) = hmac
{
117 if hmac
!= expected_hmac
{
118 bail
!("blob signature check failed");
123 BlobReaderState
::Encrypted { expected_crc, decrypt_reader }
=> {
124 let csum_reader
= decrypt_reader
.finish()?
.into_inner();
125 let (reader
, crc
, _
) = csum_reader
.finish()?
;
126 if crc
!= expected_crc
{
127 bail
!("blob crc check failed");
131 BlobReaderState
::EncryptedCompressed { expected_crc, decompr }
=> {
132 let decrypt_reader
= decompr
.finish().into_inner();
133 let csum_reader
= decrypt_reader
.finish()?
.into_inner();
134 let (reader
, crc
, _
) = csum_reader
.finish()?
;
135 if crc
!= expected_crc
{
136 bail
!("blob crc check failed");
144 impl <R
: Read
> Read
for DataBlobReader
<R
> {
146 fn read(&mut self, buf
: &mut [u8]) -> Result
<usize, std
::io
::Error
> {
147 match &mut self.state
{
148 BlobReaderState
::Uncompressed { csum_reader, .. }
=> {
149 csum_reader
.read(buf
)
151 BlobReaderState
::Compressed { decompr, .. }
=> {
154 BlobReaderState
::Signed { csum_reader, .. }
=> {
155 csum_reader
.read(buf
)
157 BlobReaderState
::SignedCompressed { decompr, .. }
=> {
160 BlobReaderState
::Encrypted { decrypt_reader, .. }
=> {
161 decrypt_reader
.read(buf
)
163 BlobReaderState
::EncryptedCompressed { decompr, .. }
=> {