edhoc 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -252,14 +252,17 @@ int EdhocCryptoManager::callImportKey(const void* user_context,
252
252
  std::promise<int> promise;
253
253
  std::future<int> future = promise.get_future();
254
254
 
255
- auto successHandler = [&promise, &key_id_ptr](Napi::Env env, Napi::Value result) {
255
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
256
+
257
+ auto successHandler = [&promise, &key_id_ptr, &context](Napi::Env env, Napi::Value result) {
256
258
  Napi::HandleScope scope(env);
257
259
  uint8_t* key_id = static_cast<uint8_t*>(key_id_ptr);
258
260
 
259
261
  if (result.IsTypedArray()) {
260
262
  Napi::Uint8Array resultArray = result.As<Napi::Uint8Array>();
261
263
  if (resultArray.ElementLength() > CONFIG_LIBEDHOC_KEY_ID_LEN) {
262
- throw std::runtime_error(kErrorInvalidUint8ArrayLength);
264
+ context->error = Napi::Error::New(env, kErrorInvalidUint8ArrayLength);
265
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
263
266
  }
264
267
  memcpy(key_id, resultArray.Data(), resultArray.ElementLength());
265
268
  promise.set_value(EDHOC_SUCCESS);
@@ -270,25 +273,26 @@ int EdhocCryptoManager::callImportKey(const void* user_context,
270
273
  Utils::EncodeInt64ToBuffer(num, tempBuffer, &encodedLength);
271
274
 
272
275
  if (encodedLength > CONFIG_LIBEDHOC_KEY_ID_LEN) {
273
- throw std::runtime_error(kErrorEncodedUint32Length);
276
+ context->error = Napi::Error::New(env, kErrorEncodedUint32Length);
277
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
274
278
  }
275
279
 
276
280
  memcpy(key_id, tempBuffer, encodedLength);
277
281
  memset(key_id + encodedLength, 0, CONFIG_LIBEDHOC_KEY_ID_LEN - encodedLength);
278
282
  promise.set_value(EDHOC_SUCCESS);
279
283
  } else {
280
- throw std::runtime_error(kErrorExpectUint8ArrayOrNumber);
284
+ context->error = Napi::Error::New(env, kErrorExpectUint8ArrayOrNumber);
285
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
281
286
  }
282
287
  };
283
288
 
284
- auto blockingCallHandler = [this, &user_context, &promise, key_type, &raw_key, raw_key_length, successHandler](
289
+ auto blockingCallHandler = [this, &context, &promise, key_type, &raw_key, raw_key_length, successHandler](
285
290
  Napi::Env env, Napi::Function jsCallback) {
286
291
  Napi::HandleScope scope(env);
287
292
 
288
- std::vector<napi_value> args = {static_cast<const UserContext*>(user_context)->parent.Value(),
289
- Napi::Number::New(env, static_cast<int>(key_type)),
293
+ std::vector<napi_value> args = {context->parent.Value(), Napi::Number::New(env, static_cast<int>(key_type)),
290
294
  Napi::Buffer<uint8_t>::New(env, const_cast<uint8_t*>(raw_key), raw_key_length)};
291
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
295
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
292
296
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
293
297
  errorHandler);
294
298
  };
@@ -303,6 +307,8 @@ int EdhocCryptoManager::callDestroyKey(const void* user_context, void* key_id) {
303
307
  std::promise<int> promise;
304
308
  std::future<int> future = promise.get_future();
305
309
 
310
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
311
+
306
312
  // Timeout thread to ensure the callback is called
307
313
  std::shared_ptr<bool> callbackCompleted = std::make_shared<bool>(false);
308
314
  std::thread timeoutThread([callbackCompleted, &promise]() {
@@ -313,22 +319,23 @@ int EdhocCryptoManager::callDestroyKey(const void* user_context, void* key_id) {
313
319
  });
314
320
  timeoutThread.detach();
315
321
 
316
- auto successHandler = [&promise](Napi::Env env, Napi::Value result) {
322
+ auto successHandler = [&promise, &context](Napi::Env env, Napi::Value result) {
317
323
  Napi::HandleScope scope(env);
318
324
  if (!result.IsBoolean()) {
319
- throw std::runtime_error(kErrorExpectBoolean);
325
+ context->error = Napi::Error::New(env, kErrorExpectBoolean);
326
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
320
327
  }
321
328
  promise.set_value(result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_GENERIC_ERROR);
322
329
  };
323
330
 
324
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, callbackCompleted, successHandler](
331
+ auto blockingCallHandler = [this, &context, &promise, &key_id, callbackCompleted, successHandler](
325
332
  Napi::Env env, Napi::Function jsCallback) {
326
333
  *callbackCompleted = true;
327
334
  Napi::HandleScope scope(env);
328
335
  std::vector<napi_value> args = {
329
- static_cast<const UserContext*>(user_context)->parent.Value(),
336
+ context->parent.Value(),
330
337
  Napi::Buffer<uint8_t>::Copy(env, static_cast<uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN)};
331
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
338
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
332
339
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
333
340
  errorHandler);
334
341
  };
@@ -350,11 +357,14 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
350
357
  std::promise<int> promise;
351
358
  std::future<int> future = promise.get_future();
352
359
 
360
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
361
+
353
362
  auto successHandler = [&promise, &private_key, private_key_size, &private_key_length, &public_key, public_key_size,
354
- &public_key_length](Napi::Env env, Napi::Value result) {
363
+ &public_key_length, &context](Napi::Env env, Napi::Value result) {
355
364
  Napi::HandleScope scope(env);
356
365
  if (!result.IsObject()) {
357
- throw std::runtime_error(kErrorResultObjectExpected);
366
+ context->error = Napi::Error::New(env, kErrorResultObjectExpected);
367
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
358
368
  }
359
369
 
360
370
  Napi::Object resultObject = result.As<Napi::Object>();
@@ -362,18 +372,21 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
362
372
  Napi::Value publicKeyValue = resultObject.Get("publicKey");
363
373
 
364
374
  if (!privateKeyValue.IsBuffer() || !publicKeyValue.IsBuffer()) {
365
- throw std::runtime_error(kErrorKeysExpectedAsBuffers);
375
+ context->error = Napi::Error::New(env, kErrorKeysExpectedAsBuffers);
376
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
366
377
  }
367
378
 
368
379
  Napi::Buffer<uint8_t> privateKeyBuffer = privateKeyValue.As<Napi::Buffer<uint8_t>>();
369
380
  Napi::Buffer<uint8_t> publicKeyBuffer = publicKeyValue.As<Napi::Buffer<uint8_t>>();
370
381
 
371
382
  if (privateKeyBuffer.Length() > private_key_size) {
372
- throw std::runtime_error(kErrorPrivateKeyLengthExceeds);
383
+ context->error = Napi::Error::New(env, kErrorPrivateKeyLengthExceeds);
384
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
373
385
  }
374
386
 
375
387
  if (publicKeyBuffer.Length() > public_key_size) {
376
- throw std::runtime_error(kErrorPublicKeyLengthExceeds);
388
+ context->error = Napi::Error::New(env, kErrorPublicKeyLengthExceeds);
389
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
377
390
  }
378
391
 
379
392
  memcpy(private_key, privateKeyBuffer.Data(), privateKeyBuffer.Length());
@@ -384,15 +397,15 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
384
397
  promise.set_value(EDHOC_SUCCESS);
385
398
  };
386
399
 
387
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, private_key_size, public_key_size,
388
- successHandler](Napi::Env env, Napi::Function jsCallback) {
400
+ auto blockingCallHandler = [this, &context, &promise, &key_id, private_key_size, public_key_size, successHandler](
401
+ Napi::Env env, Napi::Function jsCallback) {
389
402
  Napi::HandleScope scope(env);
390
403
  std::vector<napi_value> args = {
391
- static_cast<const UserContext*>(user_context)->parent.Value(),
404
+ context->parent.Value(),
392
405
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
393
406
  Napi::Number::New(env, static_cast<size_t>(private_key_size)),
394
407
  Napi::Number::New(env, static_cast<size_t>(public_key_size))};
395
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
408
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
396
409
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
397
410
  errorHandler);
398
411
  };
@@ -413,15 +426,19 @@ int EdhocCryptoManager::callKeyAgreement(const void* user_context,
413
426
  std::promise<int> promise;
414
427
  std::future<int> future = promise.get_future();
415
428
 
416
- auto successHandler = [&promise, &shared_secret, shared_secret_size, &shared_secret_length](Napi::Env env,
417
- Napi::Value result) {
429
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
430
+
431
+ auto successHandler = [&promise, &shared_secret, shared_secret_size, &shared_secret_length, &context](
432
+ Napi::Env env, Napi::Value result) {
418
433
  Napi::HandleScope scope(env);
419
434
  if (!result.IsBuffer()) {
420
- throw std::runtime_error(kErrorExpectBuffer);
435
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
436
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
421
437
  }
422
438
  Napi::Buffer<uint8_t> sharedSecretBuffer = result.As<Napi::Buffer<uint8_t>>();
423
439
  if (sharedSecretBuffer.Length() > shared_secret_size) {
424
- throw std::runtime_error(kErrorSecretLengthExceeds);
440
+ context->error = Napi::Error::New(env, kErrorSecretLengthExceeds);
441
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
425
442
  }
426
443
  memcpy(shared_secret, sharedSecretBuffer.Data(), sharedSecretBuffer.Length());
427
444
  *shared_secret_length = sharedSecretBuffer.Length();
@@ -429,16 +446,16 @@ int EdhocCryptoManager::callKeyAgreement(const void* user_context,
429
446
  promise.set_value(EDHOC_SUCCESS);
430
447
  };
431
448
 
432
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &peer_public_key, peer_public_key_length,
449
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &peer_public_key, peer_public_key_length,
433
450
  shared_secret_size, successHandler](Napi::Env env, Napi::Function jsCallback) {
434
451
  Napi::HandleScope scope(env);
435
452
  std::vector<napi_value> args = {
436
- static_cast<const UserContext*>(user_context)->parent.Value(),
453
+ context->parent.Value(),
437
454
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
438
455
  Napi::Buffer<uint8_t>::Copy(env, peer_public_key, peer_public_key_length),
439
456
  Napi::Number::New(env, static_cast<size_t>(shared_secret_size)),
440
457
  };
441
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
458
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
442
459
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
443
460
  errorHandler);
444
461
  };
@@ -460,15 +477,19 @@ int EdhocCryptoManager::callSign(const void* user_context,
460
477
  std::future<int> future = promise.get_future();
461
478
 
462
479
  const uint8_t* kid = static_cast<const uint8_t*>(key_id);
480
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
463
481
 
464
- auto successHandler = [&promise, &signature, signature_size, &signature_length](Napi::Env env, Napi::Value result) {
482
+ auto successHandler = [&promise, &signature, signature_size, &signature_length, &context](Napi::Env env,
483
+ Napi::Value result) {
465
484
  Napi::HandleScope scope(env);
466
485
  if (!result.IsBuffer()) {
467
- throw std::runtime_error(kErrorExpectBuffer);
486
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
487
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
468
488
  }
469
489
  Napi::Buffer<uint8_t> signatureBuffer = result.As<Napi::Buffer<uint8_t>>();
470
490
  if (signatureBuffer.Length() > signature_size) {
471
- throw std::runtime_error(kErrorSignatureLengthExceeds);
491
+ context->error = Napi::Error::New(env, kErrorSignatureLengthExceeds);
492
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
472
493
  }
473
494
  memcpy(signature, signatureBuffer.Data(), signatureBuffer.Length());
474
495
  *signature_length = signatureBuffer.Length();
@@ -476,15 +497,15 @@ int EdhocCryptoManager::callSign(const void* user_context,
476
497
  promise.set_value(EDHOC_SUCCESS);
477
498
  };
478
499
 
479
- auto blockingCallHandler = [this, &user_context, &promise, kid, &input, input_length, signature_size, successHandler](
500
+ auto blockingCallHandler = [this, &context, &promise, kid, &input, input_length, signature_size, successHandler](
480
501
  Napi::Env env, Napi::Function jsCallback) {
481
502
  Napi::HandleScope scope(env);
482
503
  std::vector<napi_value> args = {
483
- static_cast<const UserContext*>(user_context)->parent.Value(),
504
+ context->parent.Value(),
484
505
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(kid), CONFIG_LIBEDHOC_KEY_ID_LEN),
485
506
  Napi::Buffer<uint8_t>::Copy(env, input, input_length),
486
507
  Napi::Number::New(env, static_cast<size_t>(signature_size))};
487
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
508
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
488
509
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
489
510
  errorHandler);
490
511
  };
@@ -504,24 +525,27 @@ int EdhocCryptoManager::callVerify(const void* user_context,
504
525
  std::promise<int> promise;
505
526
  std::future<int> future = promise.get_future();
506
527
 
507
- auto successHandler = [&promise](Napi::Env env, Napi::Value result) {
528
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
529
+
530
+ auto successHandler = [&promise, &context](Napi::Env env, Napi::Value result) {
508
531
  Napi::HandleScope scope(env);
509
532
  if (!result.IsBoolean()) {
510
- throw std::runtime_error(kErrorExpectBooleanVerify);
533
+ context->error = Napi::Error::New(env, kErrorExpectBooleanVerify);
534
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
511
535
  }
512
536
  promise.set_value(result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_CRYPTO_FAILURE);
513
537
  };
514
538
 
515
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &input, input_length, &signature,
516
- signature_length, successHandler](Napi::Env env, Napi::Function jsCallback) {
539
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &input, input_length, &signature, signature_length,
540
+ successHandler](Napi::Env env, Napi::Function jsCallback) {
517
541
  Napi::HandleScope scope(env);
518
542
  std::vector<napi_value> args = {
519
- static_cast<const UserContext*>(user_context)->parent.Value(),
543
+ context->parent.Value(),
520
544
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
521
545
  Napi::Buffer<uint8_t>::Copy(env, input, input_length),
522
546
  Napi::Buffer<uint8_t>::Copy(env, signature, signature_length),
523
547
  };
524
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
548
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
525
549
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
526
550
  errorHandler);
527
551
  };
@@ -542,15 +566,19 @@ int EdhocCryptoManager::callExtract(const void* user_context,
542
566
  std::promise<int> promise;
543
567
  std::future<int> future = promise.get_future();
544
568
 
545
- auto successHandler = [&promise, &pseudo_random_key, pseudo_random_key_size, &pseudo_random_key_length](
569
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
570
+
571
+ auto successHandler = [&promise, &pseudo_random_key, pseudo_random_key_size, &pseudo_random_key_length, &context](
546
572
  Napi::Env env, Napi::Value result) {
547
573
  Napi::HandleScope scope(env);
548
574
  if (!result.IsBuffer()) {
549
- throw std::runtime_error(kErrorExpectBuffer);
575
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
576
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
550
577
  }
551
578
  Napi::Buffer<uint8_t> randomKeyBuffer = result.As<Napi::Buffer<uint8_t>>();
552
579
  if (randomKeyBuffer.Length() > pseudo_random_key_size) {
553
- throw std::runtime_error(kErrorPseudoRandpmLengthExceeds);
580
+ context->error = Napi::Error::New(env, kErrorPseudoRandpmLengthExceeds);
581
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
554
582
  }
555
583
  memcpy(pseudo_random_key, randomKeyBuffer.Data(), randomKeyBuffer.Length());
556
584
  *pseudo_random_key_length = randomKeyBuffer.Length();
@@ -558,15 +586,15 @@ int EdhocCryptoManager::callExtract(const void* user_context,
558
586
  promise.set_value(EDHOC_SUCCESS);
559
587
  };
560
588
 
561
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &salt, salt_len, pseudo_random_key_size,
589
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &salt, salt_len, pseudo_random_key_size,
562
590
  successHandler](Napi::Env env, Napi::Function jsCallback) {
563
591
  Napi::HandleScope scope(env);
564
592
  std::vector<napi_value> args = {
565
- static_cast<const UserContext*>(user_context)->parent.Value(),
593
+ context->parent.Value(),
566
594
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
567
595
  Napi::Buffer<uint8_t>::Copy(env, salt, salt_len),
568
596
  Napi::Number::New(env, static_cast<size_t>(pseudo_random_key_size))};
569
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
597
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
570
598
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
571
599
  errorHandler);
572
600
  };
@@ -586,30 +614,34 @@ int EdhocCryptoManager::callExpand(const void* user_context,
586
614
  std::promise<int> promise;
587
615
  std::future<int> future = promise.get_future();
588
616
 
589
- auto successHandler = [&promise, &output_keying_material, output_keying_material_length](Napi::Env env,
590
- Napi::Value result) {
617
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
618
+
619
+ auto successHandler = [&promise, &output_keying_material, output_keying_material_length, &context](
620
+ Napi::Env env, Napi::Value result) {
591
621
  Napi::HandleScope scope(env);
592
622
  if (!result.IsBuffer()) {
593
- throw std::runtime_error(kErrorExpectBuffer);
623
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
624
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
594
625
  }
595
626
  Napi::Buffer<uint8_t> outputBuffer = result.As<Napi::Buffer<uint8_t>>();
596
627
  if (outputBuffer.Length() > output_keying_material_length) {
597
- throw std::runtime_error(kErrorKeyingMaterialLengthExceeds);
628
+ context->error = Napi::Error::New(env, kErrorKeyingMaterialLengthExceeds);
629
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
598
630
  }
599
631
  memcpy(output_keying_material, outputBuffer.Data(), outputBuffer.Length());
600
632
 
601
633
  promise.set_value(EDHOC_SUCCESS);
602
634
  };
603
635
 
604
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &info, info_length, output_keying_material_length,
636
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &info, info_length, output_keying_material_length,
605
637
  successHandler](Napi::Env env, Napi::Function jsCallback) {
606
638
  Napi::HandleScope scope(env);
607
639
  std::vector<napi_value> args = {
608
- static_cast<const UserContext*>(user_context)->parent.Value(),
640
+ context->parent.Value(),
609
641
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
610
642
  Napi::Buffer<uint8_t>::Copy(env, info, info_length),
611
643
  Napi::Number::New(env, static_cast<size_t>(output_keying_material_length))};
612
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
644
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
613
645
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
614
646
  errorHandler);
615
647
  };
@@ -634,15 +666,19 @@ int EdhocCryptoManager::callEncrypt(const void* user_context,
634
666
  std::promise<int> promise;
635
667
  std::future<int> future = promise.get_future();
636
668
 
637
- auto successHandler = [&promise, &ciphertext, ciphertext_size, &ciphertext_length](Napi::Env env,
638
- Napi::Value result) {
669
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
670
+
671
+ auto successHandler = [&promise, &ciphertext, ciphertext_size, &ciphertext_length, &context](Napi::Env env,
672
+ Napi::Value result) {
639
673
  Napi::HandleScope scope(env);
640
674
  if (!result.IsBuffer()) {
641
- throw std::runtime_error(kErrorExpectBuffer);
675
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
676
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
642
677
  }
643
678
  Napi::Buffer<uint8_t> ciphertextBuffer = result.As<Napi::Buffer<uint8_t>>();
644
679
  if (ciphertextBuffer.Length() > ciphertext_size) {
645
- throw std::runtime_error(kErrorBufferTooSmall);
680
+ context->error = Napi::Error::New(env, kErrorBufferTooSmall);
681
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
646
682
  }
647
683
  memcpy(ciphertext, ciphertextBuffer.Data(), ciphertextBuffer.Length());
648
684
  *ciphertext_length = ciphertextBuffer.Length();
@@ -650,18 +686,18 @@ int EdhocCryptoManager::callEncrypt(const void* user_context,
650
686
  promise.set_value(EDHOC_SUCCESS);
651
687
  };
652
688
 
653
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &nonce, nonce_length, &additional_data,
689
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &nonce, nonce_length, &additional_data,
654
690
  additional_data_length, &plaintext, plaintext_length, ciphertext_size,
655
691
  successHandler](Napi::Env env, Napi::Function jsCallback) {
656
692
  Napi::HandleScope scope(env);
657
693
  std::vector<napi_value> args = {
658
- static_cast<const UserContext*>(user_context)->parent.Value(),
694
+ context->parent.Value(),
659
695
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
660
696
  Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
661
697
  Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
662
698
  Napi::Buffer<uint8_t>::Copy(env, plaintext, plaintext_length),
663
699
  Napi::Number::New(env, static_cast<size_t>(ciphertext_size))};
664
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
700
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
665
701
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
666
702
  errorHandler);
667
703
  };
@@ -686,14 +722,19 @@ int EdhocCryptoManager::callDecrypt(const void* user_context,
686
722
  std::promise<int> promise;
687
723
  std::future<int> future = promise.get_future();
688
724
 
689
- auto successHandler = [&promise, &plaintext, plaintext_size, plaintext_length](Napi::Env env, Napi::Value result) {
725
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
726
+
727
+ auto successHandler = [&promise, &plaintext, plaintext_size, plaintext_length, &context](Napi::Env env,
728
+ Napi::Value result) {
690
729
  Napi::HandleScope scope(env);
691
730
  if (!result.IsBuffer()) {
692
- throw std::runtime_error(kErrorExpectBuffer);
731
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
732
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
693
733
  }
694
734
  Napi::Buffer<uint8_t> plaintextBuffer = result.As<Napi::Buffer<uint8_t>>();
695
735
  if (plaintextBuffer.Length() > plaintext_size) {
696
- throw std::runtime_error(kErrorPlaintextLengthExceeds);
736
+ context->error = Napi::Error::New(env, kErrorPlaintextLengthExceeds);
737
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
697
738
  }
698
739
  memcpy(plaintext, plaintextBuffer.Data(), plaintextBuffer.Length());
699
740
  *plaintext_length = plaintextBuffer.Length();
@@ -701,18 +742,18 @@ int EdhocCryptoManager::callDecrypt(const void* user_context,
701
742
  promise.set_value(EDHOC_SUCCESS);
702
743
  };
703
744
 
704
- auto blockingCallHandler = [this, &user_context, &promise, &key_id, &nonce, nonce_length, &additional_data,
745
+ auto blockingCallHandler = [this, &context, &promise, &key_id, &nonce, nonce_length, &additional_data,
705
746
  additional_data_length, &ciphertext, &ciphertext_length, plaintext_size,
706
747
  successHandler](Napi::Env env, Napi::Function jsCallback) {
707
748
  Napi::HandleScope scope(env);
708
749
  std::vector<napi_value> arguments = {
709
- static_cast<const UserContext*>(user_context)->parent.Value(),
750
+ context->parent.Value(),
710
751
  Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
711
752
  Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
712
753
  Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
713
754
  Napi::Buffer<uint8_t>::Copy(env, ciphertext, ciphertext_length),
714
755
  Napi::Number::New(env, static_cast<size_t>(plaintext_size))};
715
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
756
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
716
757
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, arguments, successHandler,
717
758
  errorHandler);
718
759
  };
@@ -732,14 +773,18 @@ int EdhocCryptoManager::callHash(const void* user_context,
732
773
  std::promise<int> promise;
733
774
  std::future<int> future = promise.get_future();
734
775
 
735
- auto successHandler = [&promise, &hash, hash_size, &hash_length](Napi::Env env, Napi::Value result) {
776
+ UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
777
+
778
+ auto successHandler = [&promise, &hash, hash_size, &hash_length, &context](Napi::Env env, Napi::Value result) {
736
779
  Napi::HandleScope scope(env);
737
780
  if (!result.IsBuffer()) {
738
- throw std::runtime_error(kErrorExpectBuffer);
781
+ context->error = Napi::Error::New(env, kErrorExpectBuffer);
782
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
739
783
  }
740
784
  Napi::Buffer<uint8_t> hashBuffer = result.As<Napi::Buffer<uint8_t>>();
741
785
  if (hashBuffer.Length() > hash_size) {
742
- throw std::runtime_error(kErrorHashLengthExceeds);
786
+ context->error = Napi::Error::New(env, kErrorHashLengthExceeds);
787
+ return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
743
788
  }
744
789
  memcpy(hash, hashBuffer.Data(), hashBuffer.Length());
745
790
  *hash_length = hashBuffer.Length();
@@ -747,15 +792,15 @@ int EdhocCryptoManager::callHash(const void* user_context,
747
792
  promise.set_value(EDHOC_SUCCESS);
748
793
  };
749
794
 
750
- auto blockingCallHandler = [this, &user_context, &promise, &input, input_length, hash_size, successHandler](
795
+ auto blockingCallHandler = [this, &context, &promise, &input, input_length, hash_size, successHandler](
751
796
  Napi::Env env, Napi::Function jsCallback) {
752
797
  Napi::HandleScope scope(env);
753
798
  std::vector<napi_value> arguments = {
754
- static_cast<const UserContext*>(user_context)->parent.Value(),
799
+ context->parent.Value(),
755
800
  Napi::Buffer<uint8_t>::Copy(env, input, input_length),
756
801
  Napi::Number::New(env, static_cast<size_t>(hash_size)),
757
802
  };
758
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR);
803
+ auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
759
804
  Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, arguments, successHandler,
760
805
  errorHandler);
761
806
  };
@@ -36,7 +36,7 @@ void EdhocEadManager::StoreEad(enum edhoc_message message, const Napi::Array& ea
36
36
  for (size_t i = 0; i < eadArray.Length(); i++) {
37
37
  Napi::Value element = eadArray.Get(i);
38
38
  if (!element.IsObject()) {
39
- throw Napi::TypeError::New(env, kErrorExpectedObject);
39
+ Napi::TypeError::New(env, kErrorExpectedObject).ThrowAsJavaScriptException();
40
40
  }
41
41
 
42
42
  Napi::Object obj = element.As<Napi::Object>();
@@ -44,7 +44,7 @@ void EdhocEadManager::StoreEad(enum edhoc_message message, const Napi::Array& ea
44
44
  Napi::Value bufferValue = obj.Get(kPropValue);
45
45
 
46
46
  if (!labelValue.IsNumber() || !bufferValue.IsBuffer()) {
47
- throw Napi::TypeError::New(env, kErrorExpectedLabelNumberAndValueBuffer);
47
+ Napi::TypeError::New(env, kErrorExpectedLabelNumberAndValueBuffer).ThrowAsJavaScriptException();
48
48
  }
49
49
 
50
50
  int label = labelValue.As<Napi::Number>().Int32Value();
@@ -25,24 +25,19 @@ EdhocExportOscoreAsyncWorker::EdhocExportOscoreAsyncWorker(Napi::Env& env,
25
25
  EdhocExportOscoreAsyncWorker::~EdhocExportOscoreAsyncWorker() {}
26
26
 
27
27
  void EdhocExportOscoreAsyncWorker::Execute() {
28
- try {
29
- size_t sender_id_length, recipient_id_length;
28
+ size_t sender_id_length, recipient_id_length;
30
29
 
31
- int ret = edhoc_export_oscore_session(&context, masterSecret.data(), masterSecret.size(), masterSalt.data(),
32
- masterSalt.size(), senderId.data(), senderId.size(), &sender_id_length,
33
- recipientId.data(), recipientId.size(), &recipient_id_length);
30
+ int ret = edhoc_export_oscore_session(&context, masterSecret.data(), masterSecret.size(), masterSalt.data(),
31
+ masterSalt.size(), senderId.data(), senderId.size(), &sender_id_length,
32
+ recipientId.data(), recipientId.size(), &recipient_id_length);
34
33
 
35
- if (ret != EDHOC_SUCCESS) {
36
- char errorMessage[kErrorBufferSize];
37
- std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
38
- SetError(errorMessage);
39
- } else {
40
- senderId.resize(sender_id_length);
41
- recipientId.resize(recipient_id_length);
42
- }
43
-
44
- } catch (const std::exception& e) {
45
- SetError(e.what());
34
+ if (ret != EDHOC_SUCCESS) {
35
+ char errorMessage[kErrorBufferSize];
36
+ std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
37
+ SetError(errorMessage);
38
+ } else {
39
+ senderId.resize(sender_id_length);
40
+ recipientId.resize(recipient_id_length);
46
41
  }
47
42
  }
48
43
 
@@ -61,15 +56,26 @@ void EdhocExportOscoreAsyncWorker::OnOK() {
61
56
  resultObj.Set(kPropSenderId, senderIdBuffer);
62
57
  resultObj.Set(kPropRecipientId, recipientIdBuffer);
63
58
 
64
- deferred.Resolve(resultObj);
65
59
  callback(env);
60
+
61
+ if (env.IsExceptionPending()) {
62
+ deferred.Reject(env.GetAndClearPendingException().Value());
63
+ } else {
64
+ deferred.Resolve(resultObj);
65
+ }
66
66
  }
67
67
 
68
68
  void EdhocExportOscoreAsyncWorker::OnError(const Napi::Error& error) {
69
69
  Napi::Env env = Env();
70
70
  Napi::HandleScope scope(env);
71
- deferred.Reject(error.Value());
71
+
72
72
  callback(env);
73
+
74
+ if (env.IsExceptionPending()) {
75
+ deferred.Reject(env.GetAndClearPendingException().Value());
76
+ } else {
77
+ deferred.Reject(error.Value());
78
+ }
73
79
  }
74
80
 
75
81
  Napi::Promise EdhocExportOscoreAsyncWorker::GetPromise() {
@@ -17,15 +17,11 @@ EdhocKeyExporterAsyncWorker::EdhocKeyExporterAsyncWorker(Napi::Env& env,
17
17
  callback(std::move(callback)) {}
18
18
 
19
19
  void EdhocKeyExporterAsyncWorker::Execute() {
20
- try {
21
- int ret = edhoc_export_prk_exporter(&context, label, output.data(), desiredLength);
22
- if (ret != EDHOC_SUCCESS) {
23
- char errorMessage[kErrorBufferSize];
24
- std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
25
- SetError(errorMessage);
26
- }
27
- } catch (const std::exception& e) {
28
- SetError(e.what());
20
+ int ret = edhoc_export_prk_exporter(&context, label, output.data(), desiredLength);
21
+ if (ret != EDHOC_SUCCESS) {
22
+ char errorMessage[kErrorBufferSize];
23
+ std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
24
+ SetError(errorMessage);
29
25
  }
30
26
  }
31
27
 
@@ -33,15 +29,27 @@ void EdhocKeyExporterAsyncWorker::OnOK() {
33
29
  Napi::Env env = Env();
34
30
  Napi::HandleScope scope(env);
35
31
  auto outputBuffer = Napi::Buffer<uint8_t>::Copy(env, output.data(), output.size());
36
- deferred.Resolve(outputBuffer);
32
+
37
33
  callback(env);
34
+
35
+ if (env.IsExceptionPending()) {
36
+ deferred.Reject(env.GetAndClearPendingException().Value());
37
+ } else {
38
+ deferred.Resolve(outputBuffer);
39
+ }
38
40
  }
39
41
 
40
42
  void EdhocKeyExporterAsyncWorker::OnError(const Napi::Error& error) {
41
43
  Napi::Env env = Env();
42
44
  Napi::HandleScope scope(env);
43
- deferred.Reject(error.Value());
45
+
44
46
  callback(env);
47
+
48
+ if (env.IsExceptionPending()) {
49
+ deferred.Reject(env.GetAndClearPendingException().Value());
50
+ } else {
51
+ deferred.Reject(error.Value());
52
+ }
45
53
  }
46
54
 
47
55
  Napi::Promise EdhocKeyExporterAsyncWorker::GetPromise() {