Reputation: 199
I use following code to decrypt a file:
FileSource fe(fileUrl.c_str(), false,
new AuthenticatedDecryptionFilter(decryptor, new FileSink(
std::string(fileUrl).c_str()), CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION | CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END ));
size_t BLOCK_SIZE = 16384;
while (remaining && !fe.SourceExhausted()) {
const unsigned int req = STDMIN(remaining, BLOCK_SIZE);
fe.Pump(req);
fe.Flush(false);
remaining -= req;
}
fe.MessageEnd();
If i try to do this without the fe.MessageEnd(), my decrypted File is 16 bytes short. So i thought i need to call MessageEnd() to fix this problem. But if i call MessageEnd() i get Follwing Exception: BufferedTransformation: this object doesn't allow input
Upvotes: 1
Views: 579
Reputation: 102376
if i call MessageEnd() I get Follwing Exception:
BufferedTransformation: this object doesn't allow input
...
Correct. The FileSource
is a source, and the message must exist. You can't call Put
or Put2
on the source to add additional data to the message.
I think you have two options to take more control over the signals.
First
Call Flush
on the Source
.
const int opts = AuthenticatedDecryptionFilter::THROW_EXCEPTION |
AuthenticatedDecryptionFilter::MAC_AT_END;
FileSource fe(fileUrl.c_str(), false,
new AuthenticatedDecryptionFilter(decryptor, new FileSink(
std::string(fileUrl).c_str()), opts));
fe.Flush(true);
Also see the comments for Flush
at Filter::Flush in the manual.
Second
Stash a pointer to the filter and call MessageEnd
on it.
const int opts = AuthenticatedDecryptionFilter::THROW_EXCEPTION |
AuthenticatedDecryptionFilter::MAC_AT_END;
AuthenticatedDecryptionFilter* adf = NULL;
FileSource fe(fileUrl.c_str(), false,
adf = new AuthenticatedDecryptionFilter(decryptor, new FileSink(
std::string(fileUrl).c_str()), opts));
adf.MessageEnd();
This is kind of unusual, so I'm not sure what side effects you will encounter.
Don't delete the pointer. The FileSource
will delete it when it goes out of scope at the closing brace.
... my decrypted file is 16 bytes short...
In my opinion, this is the problem you should pursue if calling Flush
on the Source
does not work for you.
Also keep in mind... The output of AuthenticatedEncryptionFilter
is the 2-tuple {ciphertext,mac}
, so you get ciphertext expansion of 16-bytes because of the MAC. Later, when you use AuthenticatedDecryptionFilter
, the mac is removed after verifying it. So the recovered text should be the same size as the plain text, both of which should be 16-bytes less than the cipher text.
The thing I am not clear about is, are things working as expected but you don't realize that's how its supposed to work. Or are you really loosing 16-bytes of recovered text somewhere.
Upvotes: 1