@@ -59,7 +59,7 @@ struct CDoc1Writer::Private final: public XMLWriter
5959 std::vector<Recipient> rcpts;
6060
6161 int64_t writeEncryptionProperties (bool use_ddoc);
62- int64_t writeKeyInfo (bool use_ddoc, const Crypto::Key& transportKey);
62+ int64_t writeKeyInfo (bool use_ddoc, const std::vector<Recipient> &rcpts, const Crypto::Key& transportKey);
6363 int64_t writeRecipient (const std::vector<uint8_t > &recipient, const Crypto::Key& transportKey);
6464};
6565
@@ -90,7 +90,7 @@ int64_t CDoc1Writer::Private::writeEncryptionProperties(bool use_ddoc)
9090 return writeEndElement (Private::DENC); // EncryptedData
9191}
9292
93- int64_t CDoc1Writer::Private::writeKeyInfo (bool use_ddoc, const Crypto::Key& transportKey)
93+ int64_t CDoc1Writer::Private::writeKeyInfo (bool use_ddoc, const std::vector<Recipient> &rcpts, const Crypto::Key& transportKey)
9494{
9595 RET_ERROR (writeStartElement (Private::DENC, " EncryptedData" ,
9696 {{" MimeType" , use_ddoc ? " http://www.sk.ee/DigiDoc/v1.3.0/digidoc.xsd" : " application/octet-stream" }}));
@@ -230,43 +230,38 @@ int64_t CDoc1Writer::Private::writeRecipient(const std::vector<uint8_t> &recipie
230230libcdoc::result_t
231231CDoc1Writer::encrypt (libcdoc::MultiDataSource& src, const std::vector<libcdoc::Recipient>& keys)
232232{
233+ if (keys.empty ())
234+ return WORKFLOW_ERROR;
233235 RET_ERROR (beginEncryption ());
234236 d->rcpts = keys;
235237 Crypto::Key transportKey = Crypto::generateKey (d->method );
236238 int n_components = src.getNumComponents ();
237239 bool use_ddoc = (n_components > 1 ) || (n_components == libcdoc::NOT_IMPLEMENTED);
238240
239- RET_ERROR (d->writeKeyInfo (use_ddoc, transportKey));
240- RET_ERROR (d->writeElement (Private::DENC, " CipherData" , [&]() -> int64_t {
241- std::vector<uint8_t > data;
242- data.reserve (16384 );
243- VectorConsumer vcons (data);
244- EncryptionConsumer enc (vcons, d->method , transportKey);
245- std::string name;
246- int64_t size;
247- if (use_ddoc) {
248- DDOCWriter ddoc (enc);
249- result_t result;
250- for (result = src.next (name, size); result == OK; result = src.next (name, size)) {
251- std::vector<uint8_t > contents;
252- VectorConsumer vcons (contents);
253- RET_ERROR (src.readAll (vcons));
254- RET_ERROR (vcons.close ());
255- RET_ERROR (ddoc.addFile (name, " application/octet-stream" , contents));
256- d->files .push_back ({name, contents.size ()});
241+ RET_ERROR (d->writeKeyInfo (use_ddoc, keys, transportKey));
242+ RET_ERROR (d->writeElement (Private::DENC, " CipherData" , [&] {
243+ return d->writeBase64Element (Private::DENC, " CipherValue" , [&](DataConsumer &dst) -> int64_t {
244+ EncryptionConsumer enc (dst, d->method , transportKey);
245+ std::string name;
246+ int64_t size;
247+ if (use_ddoc) {
248+ DDOCWriter ddoc (enc);
249+ result_t result;
250+ for (result = src.next (name, size); result == OK; result = src.next (name, size)) {
251+ RET_ERROR (ddoc.addFile (name, " application/octet-stream" , size, src));
252+ d->files .push_back ({name, size_t (size)});
253+ }
254+ if (result != END_OF_STREAM)
255+ return result;
256+ } else {
257+ RET_ERROR (src.next (name, size));
258+ if (auto rv = src.readAll (enc); rv >= 0 )
259+ d->files .push_back ({std::move (name), size_t (rv)});
260+ else
261+ return rv;
257262 }
258- if (result != END_OF_STREAM)
259- return result;
260- } else {
261- RET_ERROR (src.next (name, size));
262- if (auto rv = src.readAll (enc); rv >= 0 )
263- d->files .push_back ({std::move (name), size_t (rv)});
264- else
265- return rv;
266- }
267- RET_ERROR (enc.close ());
268- RET_ERROR (vcons.close ());
269- return d->writeBase64Element (Private::DENC, " CipherValue" , data);
263+ return enc.close ();
264+ });
270265 }));
271266 RET_ERROR (d->writeEncryptionProperties (use_ddoc));
272267 d.reset ();
@@ -318,22 +313,19 @@ CDoc1Writer::finishEncryption()
318313 bool use_ddoc = d->files .size () > 1 ;
319314 libcdoc::Crypto::Key transportKey = libcdoc::Crypto::generateKey (d->method );
320315
321- RET_ERROR (d->writeKeyInfo (use_ddoc, transportKey));
316+ RET_ERROR (d->writeKeyInfo (use_ddoc, d-> rcpts , transportKey));
322317 RET_ERROR (d->writeElement (Private::DENC, " CipherData" , [&] {
323- std::vector<uint8_t > data;
324- data.reserve (16384 );
325- VectorConsumer vcons (data);
326- EncryptionConsumer enc (vcons, d->method , transportKey);
327- if (use_ddoc)
328- {
329- for (DDOCWriter ddoc (enc); const FileEntry& file : d->files )
330- RET_ERROR (ddoc.addFile (file.name , " application/octet-stream" , file.data ));
331- }
332- else
333- RET_ERROR (VectorSource (d->files .back ().data ).readAll (enc));
334- RET_ERROR (enc.close ());
335- RET_ERROR (vcons.close ());
336- return d->writeBase64Element (Private::DENC, " CipherValue" , data);
318+ return d->writeBase64Element (Private::DENC, " CipherValue" , [&](DataConsumer &dst) -> int64_t {
319+ EncryptionConsumer enc (dst, d->method , transportKey);
320+ if (use_ddoc)
321+ {
322+ for (DDOCWriter ddoc (enc); const FileEntry& file : d->files )
323+ RET_ERROR (ddoc.addFile (file.name , " application/octet-stream" , file.data ));
324+ }
325+ else
326+ RET_ERROR (VectorSource (d->files .back ().data ).readAll (enc));
327+ return enc.close ();
328+ });
337329 }));
338330 RET_ERROR (d->writeEncryptionProperties (use_ddoc));
339331 d.reset ();
0 commit comments