@@ -63,8 +63,8 @@ CDoc2Writer::writeHeader(const std::vector<libcdoc::Recipient> &recipients)
6363 return rv;
6464 }
6565
66- auto hhk = libcdoc::Crypto::expand (fmk, { libcdoc::CDoc2::HMAC. cbegin (), libcdoc::CDoc2::HMAC. cend ()} );
67- auto cek = libcdoc::Crypto::expand (fmk, { libcdoc::CDoc2::CEK. cbegin (), libcdoc::CDoc2::CEK. cend ()} );
66+ auto hhk = libcdoc::Crypto::expand (fmk, libcdoc::CDoc2::HMAC);
67+ auto cek = libcdoc::Crypto::expand (fmk, libcdoc::CDoc2::CEK);
6868 std::fill (fmk.begin (), fmk.end (), 0 );
6969 LOG_TRACE_KEY (" cek: {}" , cek);
7070 LOG_TRACE_KEY (" hhk: {}" , hhk);
@@ -202,6 +202,25 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
202202 const libcdoc::Recipient& rcpt = recipients.at (rcpt_idx);
203203 if (rcpt.isPKI ()) {
204204 std::vector<uint8_t > key_material, kek;
205+ std::string send_url;
206+ if (rcpt.isKeyServer ()) {
207+ if (!conf) {
208+ setLastError (" Configuration is missing" );
209+ LOG_ERROR (" {}" , last_error);
210+ return libcdoc::CONFIGURATION_ERROR;
211+ }
212+ if (!network) {
213+ setLastError (" Network backend is missing" );
214+ LOG_ERROR (" {}" , last_error);
215+ return libcdoc::CONFIGURATION_ERROR;
216+ }
217+ send_url = conf->getValue (rcpt.server_id , libcdoc::Configuration::KEYSERVER_SEND_URL);
218+ if (send_url.empty ()) {
219+ setLastError (" Missing keyserver URL for ID " + rcpt.server_id );
220+ LOG_ERROR (" {}" , last_error);
221+ return libcdoc::CONFIGURATION_ERROR;
222+ }
223+ }
205224 if (rcpt.pk_type == libcdoc::Recipient::PKType::RSA) {
206225 crypto->random (kek, libcdoc::CDoc2::KEY_LEN);
207226 if (libcdoc::Crypto::xor_data (xor_key, fmk, kek) != libcdoc::OK) {
@@ -218,9 +237,25 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
218237 key_material = libcdoc::Crypto::encrypt (publicKey.get (), RSA_PKCS1_OAEP_PADDING, kek);
219238
220239 LOG_TRACE_KEY (" publicKeyDer: {}" , rcpt.rcpt_key );
221- LOG_TRACE_KEY (" kek: {}" , kek);
222- LOG_TRACE_KEY (" fmk_xor_kek: {}" , xor_key);
223240 LOG_TRACE_KEY (" enc_kek: {}" , key_material);
241+ LOG_TRACE_KEY (" kek: {}" , kek);
242+ LOG_TRACE_KEY (" xor: {}" , xor_key);
243+ if (rcpt.isKeyServer ()) {
244+ libcdoc::NetworkBackend::CapsuleInfo cinfo;
245+ auto result = network->sendKey (cinfo, send_url, rcpt.rcpt_key , key_material, " rsa" , rcpt.expiry_ts );
246+ if (result < 0 ) {
247+ setLastError (network->getLastErrorStr (result));
248+ LOG_ERROR (" {}" , last_error);
249+ return libcdoc::IO_ERROR;
250+ }
251+
252+ LOG_DBG (" Keyserver Id: {}" , rcpt.server_id );
253+ LOG_DBG (" Transaction Id: {}" , cinfo.transaction_id );
254+
255+ fb_rcpts.push_back (createRSAServerCapsule (builder, rcpt, cinfo.transaction_id , cinfo.expiry_time , xor_key));
256+ } else {
257+ fb_rcpts.push_back (createRSACapsule (builder, rcpt, key_material, xor_key));
258+ }
224259 } else {
225260 auto publicKey = libcdoc::Crypto::fromECPublicKeyDer (rcpt.rcpt_key , NID_secp384r1);
226261 if (!publicKey) {
@@ -232,12 +267,9 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
232267 std::vector<uint8_t > sharedSecret = libcdoc::Crypto::deriveSharedSecret (ephKey.get (), publicKey.get ());
233268 key_material = libcdoc::Crypto::toPublicKeyDer (ephKey.get ());
234269 std::vector<uint8_t > kekPm = libcdoc::Crypto::extract (sharedSecret, std::vector<uint8_t >(libcdoc::CDoc2::KEKPREMASTER.cbegin (), libcdoc::CDoc2::KEKPREMASTER.cend ()));
235- std::string info_str = std::string () + libcdoc::CDoc2::KEK.data () +
236- cdoc20::header::EnumNameFMKEncryptionMethod (cdoc20::header::FMKEncryptionMethod::XOR) +
237- std::string (rcpt.rcpt_key .cbegin (), rcpt.rcpt_key .cend ()) +
238- std::string (key_material.cbegin (), key_material.cend ());
270+ std::string info_str = libcdoc::CDoc2::getSaltForExpand (key_material, rcpt.rcpt_key );
239271
240- kek = libcdoc::Crypto::expand (kekPm, std::vector< uint8_t >( info_str. cbegin (), info_str. cend ()) , fmk.size ());
272+ kek = libcdoc::Crypto::expand (kekPm, info_str, fmk.size ());
241273 if (libcdoc::Crypto::xor_data (xor_key, fmk, kek) != libcdoc::OK) {
242274 setLastError (" Internal error" );
243275 LOG_ERROR (" {}" , last_error);
@@ -249,65 +281,11 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
249281 LOG_TRACE_KEY (" ephPublicKeyDer: {}" , key_material);
250282 LOG_TRACE_KEY (" sharedSecret: {}" , sharedSecret);
251283 LOG_TRACE_KEY (" kekPm: {}" , kekPm);
252- }
253- LOG_TRACE_KEY (" kek: {}" , kek);
254- LOG_TRACE_KEY (" xor: {}" , xor_key);
255-
256- if (rcpt.pk_type == libcdoc::Recipient::PKType::RSA) {
257- if (rcpt.isKeyServer ()) {
258- if (!conf) {
259- setLastError (" Configuration is missing" );
260- LOG_ERROR (" {}" , last_error);
261- return libcdoc::CONFIGURATION_ERROR;
262- }
263- if (!network) {
264- setLastError (" Network backend is missing" );
265- LOG_ERROR (" {}" , last_error);
266- return libcdoc::CONFIGURATION_ERROR;
267- }
268- std::string send_url = conf->getValue (rcpt.server_id , libcdoc::Configuration::KEYSERVER_SEND_URL);
269- if (send_url.empty ()) {
270- setLastError (" Missing keyserver URL for ID " + rcpt.server_id );
271- LOG_ERROR (" {}" , last_error);
272- return libcdoc::CONFIGURATION_ERROR;
273- }
274- libcdoc::NetworkBackend::CapsuleInfo cinfo;
275- int result = network->sendKey (cinfo, send_url, rcpt.rcpt_key , key_material, " RSA" , rcpt.expiry_ts );
276- if (result < 0 ) {
277- setLastError (network->getLastErrorStr (result));
278- LOG_ERROR (" {}" , last_error);
279- return libcdoc::IO_ERROR;
280- }
281-
282- LOG_DBG (" Keyserver Id: {}" , rcpt.server_id );
283- LOG_DBG (" Transaction Id: {}" , cinfo.transaction_id );
284-
285- auto record = createRSAServerCapsule (builder, rcpt, cinfo.transaction_id , cinfo.expiry_time , xor_key);
286- fb_rcpts.push_back (std::move (record));
287- } else {
288- auto record = createRSACapsule (builder, rcpt, key_material, xor_key);
289- fb_rcpts.push_back (std::move (record));
290- }
291- } else {
284+ LOG_TRACE_KEY (" kek: {}" , kek);
285+ LOG_TRACE_KEY (" xor: {}" , xor_key);
292286 if (rcpt.isKeyServer ()) {
293- if (!conf) {
294- setLastError (" Configuration is missing" );
295- LOG_ERROR (" {}" , last_error);
296- return libcdoc::CONFIGURATION_ERROR;
297- }
298- if (!network) {
299- setLastError (" Network backend is missing" );
300- LOG_ERROR (" {}" , last_error);
301- return libcdoc::CONFIGURATION_ERROR;
302- }
303- std::string send_url = conf->getValue (rcpt.server_id , libcdoc::Configuration::KEYSERVER_SEND_URL);
304- if (send_url.empty ()) {
305- setLastError (" Missing keyserver URL for ID " + rcpt.server_id );
306- LOG_ERROR (" {}" , last_error);
307- return libcdoc::CONFIGURATION_ERROR;
308- }
309287 libcdoc::NetworkBackend::CapsuleInfo cinfo;
310- int result = network->sendKey (cinfo, send_url, rcpt.rcpt_key , key_material, " ecc_secp384r1" , rcpt.expiry_ts );
288+ auto result = network->sendKey (cinfo, send_url, rcpt.rcpt_key , key_material, " ecc_secp384r1" , rcpt.expiry_ts );
311289 if (result < 0 ) {
312290 setLastError (network->getLastErrorStr (result));
313291 LOG_ERROR (" {}" , last_error);
@@ -317,11 +295,9 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
317295 LOG_DBG (" Keyserver Id: {}" , rcpt.server_id );
318296 LOG_DBG (" Transaction Id: {}" , cinfo.transaction_id );
319297
320- auto record = createECCServerCapsule (builder, rcpt, cinfo.transaction_id , cinfo.expiry_time , xor_key);
321- fb_rcpts.push_back (std::move (record));
298+ fb_rcpts.push_back (createECCServerCapsule (builder, rcpt, cinfo.transaction_id , cinfo.expiry_time , xor_key));
322299 } else {
323- auto record = createECCCapsule (builder, rcpt, key_material, xor_key);
324- fb_rcpts.push_back (std::move (record));
300+ fb_rcpts.push_back (createECCCapsule (builder, rcpt, key_material, xor_key));
325301 }
326302 }
327303 } else if (rcpt.isSymmetric ()) {
@@ -344,11 +320,11 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
344320 setLastError (crypto->getLastErrorStr (result));
345321 return result;
346322 }
347- std::vector<uint8_t > kek = libcdoc::Crypto::expand (kek_pm, std::vector< uint8_t >( info_str. cbegin (), info_str. cend ()) , libcdoc::CDoc2::KEY_LEN);
323+ std::vector<uint8_t > kek = libcdoc::Crypto::expand (kek_pm, info_str, libcdoc::CDoc2::KEY_LEN);
348324
349325 LOG_DBG (" Label: {}" , rcpt.label );
350326 LOG_DBG (" KDF iter: {}" , rcpt.kdf_iter );
351- LOG_DBG (" info: {}" , toHex (std::vector< uint8_t >( info_str. cbegin (), info_str. cend ()) ));
327+ LOG_DBG (" info: {}" , toHex (info_str));
352328 LOG_TRACE_KEY (" salt: {}" , salt);
353329 LOG_TRACE_KEY (" pw_salt: {}" , pw_salt);
354330 LOG_TRACE_KEY (" kek_pm: {}" , kek_pm);
@@ -361,11 +337,9 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
361337 return libcdoc::CRYPTO_ERROR;
362338 }
363339 if (rcpt.kdf_iter > 0 ) {
364- auto offs = createPasswordCapsule (builder, rcpt, salt, pw_salt, xor_key);
365- fb_rcpts.push_back (std::move (offs));
340+ fb_rcpts.push_back (createPasswordCapsule (builder, rcpt, salt, pw_salt, xor_key));
366341 } else {
367- auto offs = createSymmetricKeyCapsule (builder, rcpt, salt, xor_key);
368- fb_rcpts.push_back (std::move (offs));
342+ fb_rcpts.push_back (createSymmetricKeyCapsule (builder, rcpt, salt, xor_key));
369343 }
370344 } else if (rcpt.isKeyShare ()) {
371345 std::string url_list = conf->getValue (rcpt.server_id , libcdoc::Configuration::SHARE_SERVER_URLS);
@@ -405,7 +379,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
405379 // KEK_i = HKDF_Expand(KEK_i_pm, "CDOC2kek" + FMKEncryptionMethod + RecipientInfo_i, L)
406380 std::string info_str = std::string (" CDOC2kek" ) + cdoc20::header::EnumNameFMKEncryptionMethod (cdoc20::header::FMKEncryptionMethod::XOR) + RecipientInfo_i;
407381 LOG_DBG (" Info: {}" , info_str);
408- std::vector<uint8_t > kek = libcdoc::Crypto::expand (kek_pm, std::vector< uint8_t >( info_str. cbegin (), info_str. cend ()) );
382+ std::vector<uint8_t > kek = libcdoc::Crypto::expand (kek_pm, info_str);
409383 LOG_TRACE_KEY (" kek: {}" , kek);
410384 if (kek.empty ()) return libcdoc::CRYPTO_ERROR;
411385 if (libcdoc::Crypto::xor_data (xor_key, fmk, kek) != libcdoc::OK) {
0 commit comments