Skip to content

Commit 1ba83cb

Browse files
author
Lauris Kaplinski
committed
Report decryption error instead of zlib/tar error if stream is corrupted
Signed-off-by: Lauris Kaplinski <lauris@raulwalter.com>
1 parent f547bb8 commit 1ba83cb

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

cdoc/CDoc2Reader.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,20 @@ struct CDoc2Reader::Private {
8787
std::unique_ptr<libcdoc::DecryptionSource> dec;
8888
std::unique_ptr<libcdoc::ZSource> zsrc;
8989
std::unique_ptr<libcdoc::TarSource> tar;
90+
91+
result_t decryptAllAndClose() {
92+
std::array<uint8_t, 1024> buf;
93+
result_t rv = dec->read(buf.data(), buf.size());
94+
while (rv == buf.size()) {
95+
rv = dec->read(buf.data(), buf.size());
96+
}
97+
if (rv < 0) return rv;
98+
zsrc.reset();
99+
tar.reset();
100+
rv = dec->close();
101+
dec.reset();
102+
return rv;
103+
}
90104
};
91105

92106
CDoc2Reader::~CDoc2Reader()
@@ -418,8 +432,13 @@ CDoc2Reader::nextFile(std::string& name, int64_t& size)
418432
LOG_ERROR("{}", last_error);
419433
return libcdoc::WORKFLOW_ERROR;
420434
}
421-
result_t result = priv->tar->next(name, size);
422-
if (result != OK) {
435+
result_t result = priv->tar->next(name, size);
436+
if (result < 0) {
437+
result_t sr = priv->decryptAllAndClose();
438+
if (sr != OK) {
439+
setLastError("Crypto payload integrity check failed");
440+
return sr;
441+
}
423442
setLastError(priv->tar->getLastErrorStr(result));
424443
}
425444
return result;
@@ -434,7 +453,12 @@ CDoc2Reader::readData(uint8_t *dst, size_t size)
434453
return libcdoc::WORKFLOW_ERROR;
435454
}
436455
result_t result = priv->tar->read(dst, size);
437-
if (result != OK) {
456+
if (result < 0) {
457+
result_t sr = priv->decryptAllAndClose();
458+
if (sr != OK) {
459+
setLastError("Crypto payload integrity check failed");
460+
return sr;
461+
}
438462
setLastError(priv->tar->getLastErrorStr(result));
439463
}
440464
return result;
@@ -443,11 +467,15 @@ CDoc2Reader::readData(uint8_t *dst, size_t size)
443467
libcdoc::result_t
444468
CDoc2Reader::finishDecryption()
445469
{
470+
if (!priv->tar) {
471+
setLastError("finishDecryption() called before beginDecryption()");
472+
LOG_ERROR("{}", last_error);
473+
return libcdoc::WORKFLOW_ERROR;
474+
}
446475
if (!priv->zsrc->isEof()) {
447476
setLastError(t_("CDoc contains additional payload data that is not part of content"));
448477
LOG_WARN("{}", last_error);
449478
}
450-
451479
setLastError({});
452480
priv->zsrc.reset();
453481
priv->tar.reset();

test/libcdoc_boost.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,16 +499,16 @@ BOOST_FIXTURE_TEST_CASE_WITH_DECOR(CDoc2DecryptErrors, DecryptFixture,
499499
BOOST_TEST(rdr->getFMK(fmk, 0) == libcdoc::OK);
500500
BOOST_TEST(rdr->beginDecryption(fmk) == libcdoc::OK);
501501
libcdoc::result_t rv = rdr->nextFile(fi);
502-
BOOST_TEST(((rv == libcdoc::OK) || (rv == libcdoc::ZLIB_ERROR)));
502+
BOOST_TEST(((rv == libcdoc::OK) || (rv == libcdoc::CRYPTO_ERROR)));
503503
for (int i = 0; i < 4; i++) {
504504
rv = rdr->readData(buf, 256);
505-
BOOST_TEST(((rv == 256) || (rv == libcdoc::ZLIB_ERROR)));
505+
BOOST_TEST(((rv == 256) || (rv == libcdoc::CRYPTO_ERROR)));
506506
}
507507
rv = rdr->nextFile(fi);
508-
BOOST_TEST(((rv == libcdoc::OK) || (rv == libcdoc::ZLIB_ERROR)));
508+
BOOST_TEST(((rv == libcdoc::OK) || (rv == libcdoc::CRYPTO_ERROR)));
509509
rv = rdr->readData(buf, 256);
510-
BOOST_TEST(((rv == 255) || (rv == libcdoc::ZLIB_ERROR)));
511-
BOOST_TEST(rdr->finishDecryption() == libcdoc::CRYPTO_ERROR);
510+
BOOST_TEST(((rv == 255) || (rv == libcdoc::CRYPTO_ERROR)));
511+
BOOST_TEST(rdr->finishDecryption() == libcdoc::WORKFLOW_ERROR);
512512
delete rdr;
513513
}
514514
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)