2626#include " XmlWriter.h"
2727#include " utils/memory.h"
2828
29- #define OPENSSL_SUPPRESS_DEPRECATED
30-
3129#include < openssl/x509.h>
3230
3331using namespace libcdoc ;
@@ -94,7 +92,8 @@ int64_t CDoc1Writer::Private::writeEncryptionProperties(bool use_ddoc)
9492
9593int64_t CDoc1Writer::Private::writeKeyInfo (bool use_ddoc, const Crypto::Key& transportKey)
9694{
97- RET_ERROR (writeStartElement (Private::DENC, " EncryptedData" , {{" MimeType" , use_ddoc ? " http://www.sk.ee/DigiDoc/v1.3.0/digidoc.xsd" : " application/octet-stream" }}));
95+ RET_ERROR (writeStartElement (Private::DENC, " EncryptedData" ,
96+ {{" MimeType" , use_ddoc ? " http://www.sk.ee/DigiDoc/v1.3.0/digidoc.xsd" : " application/octet-stream" }}));
9897 RET_ERROR (writeElement (Private::DENC, " EncryptionMethod" , {{" Algorithm" , method}}));
9998 return writeElement (Private::DS, " KeyInfo" , {}, [&]() -> int64_t {
10099 for (const Recipient& key : rcpts) {
@@ -143,10 +142,7 @@ int64_t CDoc1Writer::Private::writeRecipient(const std::vector<uint8_t> &recipie
143142 {
144143 case EVP_PKEY_RSA:
145144 {
146- auto rsa = make_unique_ptr<RSA_free>(EVP_PKEY_get1_RSA (peerPKey));
147- encryptedData.resize (size_t (RSA_size (rsa.get ())));
148- RSA_public_encrypt (int (transportKey.key .size ()), transportKey.key .data (),
149- encryptedData.data (), rsa.get (), RSA_PKCS1_PADDING);
145+ encryptedData = Crypto::encrypt (peerPKey, RSA_PKCS1_PADDING, transportKey.key );
150146 RET_ERROR (writeElement (Private::DENC, " EncryptionMethod" , {{" Algorithm" , Crypto::RSA_MTH}}));
151147 RET_ERROR (writeElement (Private::DS, " KeyInfo" , [&] {
152148 return writeElement (Private::DS, " X509Data" , [&] {
@@ -156,18 +152,18 @@ int64_t CDoc1Writer::Private::writeRecipient(const std::vector<uint8_t> &recipie
156152 break ;
157153 }
158154 case EVP_PKEY_EC:
159- {
160- auto *peerECKey = EVP_PKEY_get0_EC_KEY (peerPKey);
161- int curveName = EC_GROUP_get_curve_name ( EC_KEY_get0_group (peerECKey) );
162- auto priv = make_unique_ptr<EC_KEY_free>( EC_KEY_new_by_curve_name (curveName));
163- EC_KEY_generate_key (priv. get () );
164- auto pkey = make_unique_ptr<EVP_PKEY_free>( EVP_PKEY_new ()) ;
165- EVP_PKEY_set1_EC_KEY (pkey .get (), priv. get () );
166- std::vector< uint8_t > sharedSecret = libcdoc::Crypto::deriveSharedSecret (pkey. get (), peerPKey );
167-
168- std::string oid (50 , 0 );
169- oid.resize (size_t (OBJ_obj2txt (& oid[ 0 ] , int (oid.size ()), OBJ_nid2obj (curveName ), 1 )));
170- std::vector<uint8_t > SsDer = Crypto::toPublicKeyDer (pkey .get ());
155+ {
156+ auto ephKey = libcdoc::Crypto::genECKey (peerPKey);
157+ std::vector< uint8_t > sharedSecret = libcdoc::Crypto::deriveSharedSecret (ephKey. get (), peerPKey );
158+
159+ std::string groupName ( 25 , 0 );
160+ size_t len = 0 ;
161+ EVP_PKEY_get_group_name (ephKey .get (), groupName. data (), groupName. size (), &len );
162+ groupName. resize (len );
163+ auto obj = make_unique_ptr<ASN1_OBJECT_free>( OBJ_txt2obj (groupName. c_str (), 0 ));
164+ std::string oid (25 , 0 );
165+ oid.resize (size_t (OBJ_obj2txt (oid. data () , int (oid.size ()), obj. get ( ), 1 )));
166+ std::vector<uint8_t > SsDer = Crypto::toPublicKeyDer (ephKey .get ());
171167
172168 std::string encryptionMethod (libcdoc::Crypto::KWAES256_MTH);
173169 std::string concatDigest = libcdoc::Crypto::SHA384_MTH;
@@ -245,10 +241,11 @@ CDoc1Writer::encrypt(libcdoc::MultiDataSource& src, const std::vector<libcdoc::R
245241 std::vector<uint8_t > data;
246242 data.reserve (16384 );
247243 VectorConsumer vcons (data);
244+ EncryptionConsumer enc (vcons, d->method , transportKey);
248245 std::string name;
249246 int64_t size;
250247 if (use_ddoc) {
251- DDOCWriter ddoc (vcons );
248+ DDOCWriter ddoc (enc );
252249 result_t result;
253250 for (result = src.next (name, size); result == OK; result = src.next (name, size)) {
254251 std::vector<uint8_t > contents;
@@ -262,13 +259,14 @@ CDoc1Writer::encrypt(libcdoc::MultiDataSource& src, const std::vector<libcdoc::R
262259 return result;
263260 } else {
264261 RET_ERROR (src.next (name, size));
265- if (auto rv = src.readAll (vcons ); rv >= 0 )
262+ if (auto rv = src.readAll (enc ); rv >= 0 )
266263 d->files .push_back ({std::move (name), size_t (rv)});
267264 else
268265 return rv;
269266 }
267+ RET_ERROR (enc.close ());
270268 RET_ERROR (vcons.close ());
271- return d->writeBase64Element (Private::DENC, " CipherValue" , libcdoc::Crypto::encrypt (d-> method , transportKey, data) );
269+ return d->writeBase64Element (Private::DENC, " CipherValue" , data);
272270 }));
273271 RET_ERROR (d->writeEncryptionProperties (use_ddoc));
274272 d.reset ();
@@ -322,16 +320,20 @@ CDoc1Writer::finishEncryption()
322320
323321 RET_ERROR (d->writeKeyInfo (use_ddoc, transportKey));
324322 RET_ERROR (d->writeElement (Private::DENC, " CipherData" , [&] {
325- if (!use_ddoc)
326- return d->writeBase64Element (Private::DENC, " CipherValue" , libcdoc::Crypto::encrypt (d->method , transportKey, d->files .back ().data ));
327323 std::vector<uint8_t > data;
328324 data.reserve (16384 );
329325 VectorConsumer vcons (data);
330- for (DDOCWriter ddoc (vcons); const FileEntry& file : d->files ) {
331- RET_ERROR (ddoc.addFile (file.name , " application/octet-stream" , file.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 ));
332331 }
332+ else
333+ RET_ERROR (VectorSource (d->files .back ().data ).readAll (enc));
334+ RET_ERROR (enc.close ());
333335 RET_ERROR (vcons.close ());
334- return d->writeBase64Element (Private::DENC, " CipherValue" , libcdoc::Crypto::encrypt (d-> method , transportKey, data) );
336+ return d->writeBase64Element (Private::DENC, " CipherValue" , data);
335337 }));
336338 RET_ERROR (d->writeEncryptionProperties (use_ddoc));
337339 d.reset ();
0 commit comments