@@ -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
92106CDoc2Reader::~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)
443467libcdoc::result_t
444468CDoc2Reader::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 ();
0 commit comments