edhoc 1.2.3 → 1.3.0

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.
Files changed (41) hide show
  1. package/binding.gyp +2 -2
  2. package/dist/edhoc.d.ts +4 -0
  3. package/dist/edhoc.d.ts.map +1 -1
  4. package/include/{LibEDHOC.h → Binding.h} +60 -40
  5. package/include/EdhocComposeAsyncWorker.h +8 -22
  6. package/include/EdhocCredentialManager.h +9 -25
  7. package/include/EdhocCryptoManager.h +27 -43
  8. package/include/EdhocEadManager.h +3 -4
  9. package/include/EdhocExportOscoreAsyncWorker.h +10 -27
  10. package/include/EdhocKeyExporterAsyncWorker.h +8 -28
  11. package/include/EdhocKeyUpdateAsyncWorker.h +7 -24
  12. package/include/EdhocProcessAsyncWorker.h +11 -36
  13. package/include/RunningContext.h +102 -0
  14. package/include/Utils.h +2 -46
  15. package/package.json +1 -2
  16. package/prebuilds/android-arm/edhoc.armv7.node +0 -0
  17. package/prebuilds/android-arm64/edhoc.armv8.node +0 -0
  18. package/prebuilds/darwin-arm64/edhoc.node +0 -0
  19. package/prebuilds/darwin-x64/edhoc.node +0 -0
  20. package/prebuilds/linux-arm/edhoc.armv6.node +0 -0
  21. package/prebuilds/linux-arm/edhoc.armv7.node +0 -0
  22. package/prebuilds/linux-arm64/edhoc.armv8.node +0 -0
  23. package/prebuilds/linux-x64/edhoc.glibc.node +0 -0
  24. package/prebuilds/linux-x64/edhoc.musl.node +0 -0
  25. package/prebuilds/win32-ia32/edhoc.node +0 -0
  26. package/prebuilds/win32-x64/edhoc.node +0 -0
  27. package/src/Binding.cpp +434 -0
  28. package/src/EdhocComposeAsyncWorker.cpp +39 -57
  29. package/src/EdhocCredentialManager.cpp +58 -93
  30. package/src/EdhocCryptoManager.cpp +181 -400
  31. package/src/EdhocEadManager.cpp +13 -13
  32. package/src/EdhocExportOscoreAsyncWorker.cpp +29 -45
  33. package/src/EdhocKeyExporterAsyncWorker.cpp +19 -37
  34. package/src/EdhocKeyUpdateAsyncWorker.cpp +15 -33
  35. package/src/EdhocProcessAsyncWorker.cpp +82 -96
  36. package/src/RunningContext.cpp +95 -0
  37. package/src/Utils.cpp +2 -34
  38. package/test/basic.test.ts +57 -3
  39. package/include/UserContext.h +0 -78
  40. package/src/LibEDHOC.cpp +0 -418
  41. package/test/errors.test.ts +0 -129
@@ -6,7 +6,7 @@
6
6
  #include <stdexcept>
7
7
  #include <thread>
8
8
 
9
- #include "UserContext.h"
9
+ #include "RunningContext.h"
10
10
  #include "Utils.h"
11
11
 
12
12
  static constexpr const char* kErrorInvalidUint8ArrayLength = "Returned Uint8Array length exceeds buffer length.";
@@ -29,27 +29,17 @@ static constexpr const char* kErrorResultObjectExpected = "Expected result to be
29
29
  static constexpr const char* kErrorKeysExpectedAsBuffers = "Expected keys to be buffers.";
30
30
  static constexpr const char* kErrorPrivateKeyLengthExceeds = "Private key length exceeds buffer size.";
31
31
  static constexpr const char* kErrorObjectExpected = "Object expected";
32
- static constexpr const char* kErrorFunctionExpected = "Function expected";
33
- static constexpr const char* kImportKey = "importKey";
34
- static constexpr const char* kDestroyKey = "destroyKey";
35
- static constexpr const char* kMakeKeyPair = "makeKeyPair";
36
- static constexpr const char* kKeyAgreement = "keyAgreement";
37
- static constexpr const char* kSign = "sign";
38
- static constexpr const char* kVerify = "verify";
39
- static constexpr const char* kExtract = "extract";
40
- static constexpr const char* kExpand = "expand";
41
- static constexpr const char* kEncrypt = "encrypt";
42
- static constexpr const char* kDecrypt = "decrypt";
43
- static constexpr const char* kHash = "hash";
44
-
45
- EdhocCryptoManager::EdhocCryptoManager(Napi::Object& jsCryptoManager) {
46
- if (!jsCryptoManager.IsObject()) {
32
+
33
+ EdhocCryptoManager::EdhocCryptoManager(Napi::Object& jsCryptoManager, Napi::Object& jsEdhoc) {
34
+ if (!jsCryptoManager.IsObject() || !jsEdhoc.IsObject()) {
47
35
  Napi::Error::New(jsCryptoManager.Env(), kErrorObjectExpected).ThrowAsJavaScriptException();
48
36
  }
49
37
  cryptoManagerRef = Napi::Persistent(jsCryptoManager);
38
+ edhocRef = Napi::Weak(jsEdhoc);
50
39
 
51
40
  keys.import_key = &EdhocCryptoManager::ImportKey;
52
41
  keys.destroy_key = &EdhocCryptoManager::DestroyKey;
42
+
53
43
  crypto.make_key_pair = &EdhocCryptoManager::MakeKeyPair;
54
44
  crypto.key_agreement = &EdhocCryptoManager::KeyAgreement;
55
45
  crypto.signature = &EdhocCryptoManager::Sign;
@@ -63,64 +53,25 @@ EdhocCryptoManager::EdhocCryptoManager(Napi::Object& jsCryptoManager) {
63
53
 
64
54
  EdhocCryptoManager::~EdhocCryptoManager() {
65
55
  cryptoManagerRef.Reset();
56
+ edhocRef.Reset();
66
57
  for (auto& ref : bufferReferences) {
67
58
  ref.Reset();
68
59
  }
69
60
  bufferReferences.clear();
70
61
  }
71
62
 
72
- void EdhocCryptoManager::SetupAsyncFunctions() {
73
- SetFunction(kImportKey, importTsfn);
74
- SetFunction(kDestroyKey, destroyTsfn);
75
- SetFunction(kMakeKeyPair, makeKeyPairTsfn);
76
- SetFunction(kKeyAgreement, keyAgreementTsfn);
77
- SetFunction(kSign, signTsfn);
78
- SetFunction(kVerify, verifyTsfn);
79
- SetFunction(kExtract, extractTsfn);
80
- SetFunction(kExpand, expandTsfn);
81
- SetFunction(kEncrypt, encryptTsfn);
82
- SetFunction(kDecrypt, decryptTsfn);
83
- SetFunction(kHash, hashTsfn);
84
- }
85
-
86
- void EdhocCryptoManager::CleanupAsyncFunctions() {
87
- importTsfn.Release();
88
- destroyTsfn.Release();
89
- makeKeyPairTsfn.Release();
90
- keyAgreementTsfn.Release();
91
- signTsfn.Release();
92
- verifyTsfn.Release();
93
- extractTsfn.Release();
94
- expandTsfn.Release();
95
- encryptTsfn.Release();
96
- decryptTsfn.Release();
97
- hashTsfn.Release();
98
- }
99
-
100
- void EdhocCryptoManager::SetFunction(const char* name, Napi::ThreadSafeFunction& tsfn) {
101
- Napi::Env env = cryptoManagerRef.Env();
102
- Napi::HandleScope scope(env);
103
- Napi::Function jsFunction = cryptoManagerRef.Value().Get(name).As<Napi::Function>();
104
- if (!jsFunction.IsFunction()) {
105
- Napi::Error::New(env, kErrorFunctionExpected).ThrowAsJavaScriptException();
106
- }
107
- tsfn = Napi::ThreadSafeFunction::New(env, jsFunction, name, 0, 1);
108
- }
109
-
110
63
  int EdhocCryptoManager::ImportKey(void* user_context,
111
64
  enum edhoc_key_type key_type,
112
65
  const uint8_t* raw_key,
113
66
  size_t raw_key_length,
114
67
  void* key_id) {
115
- UserContext* userContext = static_cast<UserContext*>(user_context);
116
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
117
- return cryptoManager->callImportKey(user_context, key_type, raw_key, raw_key_length, key_id);
68
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
69
+ return context->GetCryptoManager()->callImportKey(context, key_type, raw_key, raw_key_length, key_id);
118
70
  }
119
71
 
120
72
  int EdhocCryptoManager::DestroyKey(void* user_context, void* key_id) {
121
- UserContext* userContext = static_cast<UserContext*>(user_context);
122
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
123
- return cryptoManager->callDestroyKey(user_context, key_id);
73
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
74
+ return context->GetCryptoManager()->callDestroyKey(context, key_id);
124
75
  }
125
76
 
126
77
  int EdhocCryptoManager::MakeKeyPair(void* user_context,
@@ -131,9 +82,8 @@ int EdhocCryptoManager::MakeKeyPair(void* user_context,
131
82
  uint8_t* public_key,
132
83
  size_t public_key_size,
133
84
  size_t* public_key_length) {
134
- UserContext* userContext = static_cast<UserContext*>(user_context);
135
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
136
- return cryptoManager->callMakeKeyPair(user_context, key_id, private_key, private_key_size, private_key_length,
85
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
86
+ return context->GetCryptoManager()->callMakeKeyPair(context, key_id, private_key, private_key_size, private_key_length,
137
87
  public_key, public_key_size, public_key_length);
138
88
  }
139
89
 
@@ -144,9 +94,8 @@ int EdhocCryptoManager::KeyAgreement(void* user_context,
144
94
  uint8_t* shared_secret,
145
95
  size_t shared_secret_size,
146
96
  size_t* shared_secret_length) {
147
- UserContext* userContext = static_cast<UserContext*>(user_context);
148
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
149
- return cryptoManager->callKeyAgreement(user_context, key_id, peer_public_key, peer_public_key_length, shared_secret,
97
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
98
+ return context->GetCryptoManager()->callKeyAgreement(context, key_id, peer_public_key, peer_public_key_length, shared_secret,
150
99
  shared_secret_size, shared_secret_length);
151
100
  }
152
101
 
@@ -157,9 +106,8 @@ int EdhocCryptoManager::Sign(void* user_context,
157
106
  uint8_t* signature,
158
107
  size_t signature_size,
159
108
  size_t* signature_length) {
160
- UserContext* userContext = static_cast<UserContext*>(user_context);
161
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
162
- return cryptoManager->callSign(user_context, key_id, input, input_length, signature, signature_size,
109
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
110
+ return context->GetCryptoManager()->callSign(context, key_id, input, input_length, signature, signature_size,
163
111
  signature_length);
164
112
  }
165
113
 
@@ -169,9 +117,8 @@ int EdhocCryptoManager::Verify(void* user_context,
169
117
  size_t input_length,
170
118
  const uint8_t* signature,
171
119
  size_t signature_length) {
172
- UserContext* userContext = static_cast<UserContext*>(user_context);
173
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
174
- return cryptoManager->callVerify(user_context, key_id, input, input_length, signature, signature_length);
120
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
121
+ return context->GetCryptoManager()->callVerify(context, key_id, input, input_length, signature, signature_length);
175
122
  }
176
123
 
177
124
  int EdhocCryptoManager::Extract(void* user_context,
@@ -181,10 +128,9 @@ int EdhocCryptoManager::Extract(void* user_context,
181
128
  uint8_t* pseudo_random_key,
182
129
  size_t pseudo_random_key_size,
183
130
  size_t* pseudo_random_key_length) {
184
- UserContext* userContext = static_cast<UserContext*>(user_context);
185
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
186
- return cryptoManager->callExtract(user_context, key_id, salt, salt_len, pseudo_random_key, pseudo_random_key_size,
187
- pseudo_random_key_length);
131
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
132
+ return context->GetCryptoManager()->callExtract(context, key_id, salt, salt_len, pseudo_random_key,
133
+ pseudo_random_key_size, pseudo_random_key_length);
188
134
  }
189
135
 
190
136
  int EdhocCryptoManager::Expand(void* user_context,
@@ -193,9 +139,8 @@ int EdhocCryptoManager::Expand(void* user_context,
193
139
  size_t info_length,
194
140
  uint8_t* output_keying_material,
195
141
  size_t output_keying_material_length) {
196
- UserContext* userContext = static_cast<UserContext*>(user_context);
197
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
198
- return cryptoManager->callExpand(user_context, key_id, info, info_length, output_keying_material,
142
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
143
+ return context->GetCryptoManager()->callExpand(context, key_id, info, info_length, output_keying_material,
199
144
  output_keying_material_length);
200
145
  }
201
146
 
@@ -210,9 +155,8 @@ int EdhocCryptoManager::Encrypt(void* user_context,
210
155
  uint8_t* ciphertext,
211
156
  size_t ciphertext_size,
212
157
  size_t* ciphertext_length) {
213
- UserContext* userContext = static_cast<UserContext*>(user_context);
214
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
215
- return cryptoManager->callEncrypt(user_context, key_id, nonce, nonce_length, additional_data, additional_data_length,
158
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
159
+ return context->GetCryptoManager()->callEncrypt(context, key_id, nonce, nonce_length, additional_data, additional_data_length,
216
160
  plaintext, plaintext_length, ciphertext, ciphertext_size, ciphertext_length);
217
161
  }
218
162
 
@@ -227,9 +171,8 @@ int EdhocCryptoManager::Decrypt(void* user_context,
227
171
  uint8_t* plaintext,
228
172
  size_t plaintext_size,
229
173
  size_t* plaintext_length) {
230
- UserContext* userContext = static_cast<UserContext*>(user_context);
231
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
232
- return cryptoManager->callDecrypt(user_context, key_id, nonce, nonce_length, additional_data, additional_data_length,
174
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
175
+ return context->GetCryptoManager()->callDecrypt(context, key_id, nonce, nonce_length, additional_data, additional_data_length,
233
176
  ciphertext, ciphertext_length, plaintext, plaintext_size, plaintext_length);
234
177
  }
235
178
 
@@ -239,33 +182,26 @@ int EdhocCryptoManager::Hash(void* user_context,
239
182
  uint8_t* hash,
240
183
  size_t hash_size,
241
184
  size_t* hash_length) {
242
- UserContext* userContext = static_cast<UserContext*>(user_context);
243
- EdhocCryptoManager* cryptoManager = userContext->GetCryptoManager();
244
- return cryptoManager->callHash(user_context, input, input_length, hash, hash_size, hash_length);
185
+ RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
186
+ return context->GetCryptoManager()->callHash(context, input, input_length, hash, hash_size, hash_length);
245
187
  }
246
188
 
247
- int EdhocCryptoManager::callImportKey(const void* user_context,
189
+ int EdhocCryptoManager::callImportKey(RunningContext* runningContext,
248
190
  enum edhoc_key_type key_type,
249
191
  const uint8_t* raw_key,
250
192
  size_t raw_key_length,
251
193
  void* key_id_ptr) {
252
- std::promise<int> promise;
253
- std::future<int> future = promise.get_future();
254
194
 
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) {
195
+ auto successHandler = [&key_id_ptr](Napi::Env env, Napi::Value result) {
258
196
  Napi::HandleScope scope(env);
259
197
  uint8_t* key_id = static_cast<uint8_t*>(key_id_ptr);
260
198
 
261
199
  if (result.IsTypedArray()) {
262
200
  Napi::Uint8Array resultArray = result.As<Napi::Uint8Array>();
263
201
  if (resultArray.ElementLength() > CONFIG_LIBEDHOC_KEY_ID_LEN) {
264
- context->error = Napi::Error::New(env, kErrorInvalidUint8ArrayLength);
265
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
202
+ throw std::runtime_error(kErrorInvalidUint8ArrayLength);
266
203
  }
267
204
  memcpy(key_id, resultArray.Data(), resultArray.ElementLength());
268
- promise.set_value(EDHOC_SUCCESS);
269
205
  } else if (result.IsNumber()) {
270
206
  uint32_t num = result.As<Napi::Number>().Int64Value();
271
207
  uint8_t tempBuffer[CONFIG_LIBEDHOC_KEY_ID_LEN];
@@ -273,80 +209,59 @@ int EdhocCryptoManager::callImportKey(const void* user_context,
273
209
  Utils::EncodeInt64ToBuffer(num, tempBuffer, &encodedLength);
274
210
 
275
211
  if (encodedLength > CONFIG_LIBEDHOC_KEY_ID_LEN) {
276
- context->error = Napi::Error::New(env, kErrorEncodedUint32Length);
277
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
212
+ throw std::runtime_error(kErrorEncodedUint32Length);
278
213
  }
279
214
 
280
215
  memcpy(key_id, tempBuffer, encodedLength);
281
216
  memset(key_id + encodedLength, 0, CONFIG_LIBEDHOC_KEY_ID_LEN - encodedLength);
282
- promise.set_value(EDHOC_SUCCESS);
283
217
  } else {
284
- context->error = Napi::Error::New(env, kErrorExpectUint8ArrayOrNumber);
285
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
218
+ throw std::runtime_error(kErrorExpectUint8ArrayOrNumber);
286
219
  }
220
+ return EDHOC_SUCCESS;
287
221
  };
288
222
 
289
- auto blockingCallHandler = [this, &context, &promise, key_type, &raw_key, raw_key_length, successHandler](
290
- Napi::Env env, Napi::Function jsCallback) {
291
- Napi::HandleScope scope(env);
292
-
293
- std::vector<napi_value> args = {context->parent.Value(), Napi::Number::New(env, static_cast<int>(key_type)),
294
- Napi::Buffer<uint8_t>::New(env, const_cast<uint8_t*>(raw_key), raw_key_length)};
295
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
296
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
297
- errorHandler);
223
+ auto argumentsHandler = [this, key_type, raw_key, raw_key_length](Napi::Env env) {
224
+ return std::vector<napi_value> {
225
+ this->edhocRef.Value(),
226
+ Napi::Number::New(env, static_cast<int>(key_type)),
227
+ Napi::Buffer<uint8_t>::New(env, const_cast<uint8_t*>(raw_key), raw_key_length)
228
+ };
298
229
  };
299
230
 
300
- importTsfn.BlockingCall(blockingCallHandler);
301
-
302
- future.wait();
303
- return future.get();
231
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "importKey", argumentsHandler, successHandler);
304
232
  }
305
233
 
306
- int EdhocCryptoManager::callDestroyKey(const void* user_context, void* key_id) {
307
- std::promise<int> promise;
308
- std::future<int> future = promise.get_future();
309
-
310
- UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
311
-
234
+ int EdhocCryptoManager::callDestroyKey(RunningContext* runningContext, void* key_id) {
312
235
  // Timeout thread to ensure the callback is called
313
236
  std::shared_ptr<bool> callbackCompleted = std::make_shared<bool>(false);
314
- std::thread timeoutThread([callbackCompleted, &promise]() {
315
- std::this_thread::sleep_for(std::chrono::milliseconds(200));
316
- if (!*callbackCompleted) {
317
- promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
318
- }
319
- });
320
- timeoutThread.detach();
321
-
322
- auto successHandler = [&promise, &context](Napi::Env env, Napi::Value result) {
237
+ // std::thread timeoutThread([callbackCompleted]() {
238
+ // std::this_thread::sleep_for(std::chrono::milliseconds(200));
239
+ // if (!*callbackCompleted) {
240
+ // promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
241
+ // }
242
+ // });
243
+ // timeoutThread.detach();
244
+
245
+ auto successHandler = [](Napi::Env env, Napi::Value result) {
323
246
  Napi::HandleScope scope(env);
324
247
  if (!result.IsBoolean()) {
325
- context->error = Napi::Error::New(env, kErrorExpectBoolean);
326
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
248
+ throw std::runtime_error(kErrorExpectBoolean);
327
249
  }
328
- promise.set_value(result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_GENERIC_ERROR);
250
+ return result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_GENERIC_ERROR;
329
251
  };
330
252
 
331
- auto blockingCallHandler = [this, &context, &promise, &key_id, callbackCompleted, successHandler](
332
- Napi::Env env, Napi::Function jsCallback) {
253
+ auto argumentsHandler = [this, &key_id, callbackCompleted](Napi::Env env) {
333
254
  *callbackCompleted = true;
334
- Napi::HandleScope scope(env);
335
- std::vector<napi_value> args = {
336
- context->parent.Value(),
337
- Napi::Buffer<uint8_t>::Copy(env, static_cast<uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN)};
338
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
339
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
340
- errorHandler);
255
+ return std::vector<napi_value> {
256
+ this->edhocRef.Value(),
257
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN)
258
+ };
341
259
  };
342
260
 
343
- destroyTsfn.BlockingCall(blockingCallHandler);
344
-
345
- future.wait();
346
- return future.get();
261
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "destroyKey", argumentsHandler, successHandler);
347
262
  }
348
263
 
349
- int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
264
+ int EdhocCryptoManager::callMakeKeyPair(RunningContext* runningContext,
350
265
  const void* key_id,
351
266
  uint8_t* private_key,
352
267
  size_t private_key_size,
@@ -354,17 +269,11 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
354
269
  uint8_t* public_key,
355
270
  size_t public_key_size,
356
271
  size_t* public_key_length) {
357
- std::promise<int> promise;
358
- std::future<int> future = promise.get_future();
359
-
360
- UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
361
272
 
362
- auto successHandler = [&promise, &private_key, private_key_size, &private_key_length, &public_key, public_key_size,
363
- &public_key_length, &context](Napi::Env env, Napi::Value result) {
273
+ auto successHandler = [&private_key, private_key_size, &private_key_length, &public_key, public_key_size, &public_key_length](Napi::Env env, Napi::Value result) {
364
274
  Napi::HandleScope scope(env);
365
275
  if (!result.IsObject()) {
366
- context->error = Napi::Error::New(env, kErrorResultObjectExpected);
367
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
276
+ throw std::runtime_error(kErrorResultObjectExpected);
368
277
  }
369
278
 
370
279
  Napi::Object resultObject = result.As<Napi::Object>();
@@ -372,21 +281,18 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
372
281
  Napi::Value publicKeyValue = resultObject.Get("publicKey");
373
282
 
374
283
  if (!privateKeyValue.IsBuffer() || !publicKeyValue.IsBuffer()) {
375
- context->error = Napi::Error::New(env, kErrorKeysExpectedAsBuffers);
376
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
284
+ throw std::runtime_error(kErrorKeysExpectedAsBuffers);
377
285
  }
378
286
 
379
287
  Napi::Buffer<uint8_t> privateKeyBuffer = privateKeyValue.As<Napi::Buffer<uint8_t>>();
380
288
  Napi::Buffer<uint8_t> publicKeyBuffer = publicKeyValue.As<Napi::Buffer<uint8_t>>();
381
289
 
382
290
  if (privateKeyBuffer.Length() > private_key_size) {
383
- context->error = Napi::Error::New(env, kErrorPrivateKeyLengthExceeds);
384
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
291
+ throw std::runtime_error(kErrorPrivateKeyLengthExceeds);
385
292
  }
386
293
 
387
294
  if (publicKeyBuffer.Length() > public_key_size) {
388
- context->error = Napi::Error::New(env, kErrorPublicKeyLengthExceeds);
389
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
295
+ throw std::runtime_error(kErrorPublicKeyLengthExceeds);
390
296
  }
391
297
 
392
298
  memcpy(private_key, privateKeyBuffer.Data(), privateKeyBuffer.Length());
@@ -394,265 +300,185 @@ int EdhocCryptoManager::callMakeKeyPair(const void* user_context,
394
300
  memcpy(public_key, publicKeyBuffer.Data(), publicKeyBuffer.Length());
395
301
  *public_key_length = publicKeyBuffer.Length();
396
302
 
397
- promise.set_value(EDHOC_SUCCESS);
303
+ return EDHOC_SUCCESS;
398
304
  };
399
305
 
400
- auto blockingCallHandler = [this, &context, &promise, &key_id, private_key_size, public_key_size, successHandler](
401
- Napi::Env env, Napi::Function jsCallback) {
402
- Napi::HandleScope scope(env);
403
- std::vector<napi_value> args = {
404
- context->parent.Value(),
405
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
406
- Napi::Number::New(env, static_cast<size_t>(private_key_size)),
407
- Napi::Number::New(env, static_cast<size_t>(public_key_size))};
408
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
409
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
410
- errorHandler);
306
+ auto argumentsHandler = [this, &key_id, private_key_size, public_key_size](Napi::Env env) {
307
+ return std::vector<napi_value> {
308
+ this->edhocRef.Value(),
309
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
310
+ Napi::Number::New(env, static_cast<size_t>(private_key_size)),
311
+ Napi::Number::New(env, static_cast<size_t>(public_key_size))
312
+ };
411
313
  };
412
314
 
413
- makeKeyPairTsfn.BlockingCall(blockingCallHandler);
414
-
415
- future.wait();
416
- return future.get();
315
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "makeKeyPair", argumentsHandler, successHandler);
417
316
  }
418
317
 
419
- int EdhocCryptoManager::callKeyAgreement(const void* user_context,
318
+ int EdhocCryptoManager::callKeyAgreement(RunningContext* runningContext,
420
319
  const void* key_id,
421
320
  const uint8_t* peer_public_key,
422
321
  size_t peer_public_key_length,
423
322
  uint8_t* shared_secret,
424
323
  size_t shared_secret_size,
425
324
  size_t* shared_secret_length) {
426
- std::promise<int> promise;
427
- std::future<int> future = promise.get_future();
428
325
 
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) {
326
+ auto successHandler = [&shared_secret, shared_secret_size, &shared_secret_length](Napi::Env env, Napi::Value result) {
433
327
  Napi::HandleScope scope(env);
434
328
  if (!result.IsBuffer()) {
435
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
436
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
329
+ throw std::runtime_error(kErrorExpectBuffer);
437
330
  }
438
331
  Napi::Buffer<uint8_t> sharedSecretBuffer = result.As<Napi::Buffer<uint8_t>>();
439
332
  if (sharedSecretBuffer.Length() > shared_secret_size) {
440
- context->error = Napi::Error::New(env, kErrorSecretLengthExceeds);
441
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
333
+ throw std::runtime_error(kErrorSecretLengthExceeds);
442
334
  }
443
335
  memcpy(shared_secret, sharedSecretBuffer.Data(), sharedSecretBuffer.Length());
444
336
  *shared_secret_length = sharedSecretBuffer.Length();
445
337
 
446
- promise.set_value(EDHOC_SUCCESS);
338
+ return EDHOC_SUCCESS;
447
339
  };
448
340
 
449
- auto blockingCallHandler = [this, &context, &promise, &key_id, &peer_public_key, peer_public_key_length,
450
- shared_secret_size, successHandler](Napi::Env env, Napi::Function jsCallback) {
451
- Napi::HandleScope scope(env);
452
- std::vector<napi_value> args = {
453
- context->parent.Value(),
454
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
455
- Napi::Buffer<uint8_t>::Copy(env, peer_public_key, peer_public_key_length),
456
- Napi::Number::New(env, static_cast<size_t>(shared_secret_size)),
341
+ auto argumentsHandler = [this, &key_id, &peer_public_key, peer_public_key_length, shared_secret_size](Napi::Env env) {
342
+ return std::vector<napi_value> {
343
+ this->edhocRef.Value(),
344
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
345
+ Napi::Buffer<uint8_t>::Copy(env, peer_public_key, peer_public_key_length),
346
+ Napi::Number::New(env, static_cast<size_t>(shared_secret_size))
457
347
  };
458
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
459
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
460
- errorHandler);
461
348
  };
462
349
 
463
- keyAgreementTsfn.BlockingCall(blockingCallHandler);
464
-
465
- future.wait();
466
- return future.get();
350
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "keyAgreement", argumentsHandler, successHandler);
467
351
  }
468
352
 
469
- int EdhocCryptoManager::callSign(const void* user_context,
353
+ int EdhocCryptoManager::callSign(RunningContext* runningContext,
470
354
  const void* key_id,
471
355
  const uint8_t* input,
472
356
  size_t input_length,
473
357
  uint8_t* signature,
474
358
  size_t signature_size,
475
359
  size_t* signature_length) {
476
- std::promise<int> promise;
477
- std::future<int> future = promise.get_future();
478
-
479
- const uint8_t* kid = static_cast<const uint8_t*>(key_id);
480
- UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
481
360
 
482
- auto successHandler = [&promise, &signature, signature_size, &signature_length, &context](Napi::Env env,
483
- Napi::Value result) {
361
+ auto successHandler = [&signature, signature_size, &signature_length](Napi::Env env, Napi::Value result) {
484
362
  Napi::HandleScope scope(env);
485
363
  if (!result.IsBuffer()) {
486
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
487
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
364
+ throw std::runtime_error(kErrorExpectBuffer);
488
365
  }
489
366
  Napi::Buffer<uint8_t> signatureBuffer = result.As<Napi::Buffer<uint8_t>>();
490
367
  if (signatureBuffer.Length() > signature_size) {
491
- context->error = Napi::Error::New(env, kErrorSignatureLengthExceeds);
492
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
368
+ throw std::runtime_error(kErrorSignatureLengthExceeds);
493
369
  }
494
370
  memcpy(signature, signatureBuffer.Data(), signatureBuffer.Length());
495
371
  *signature_length = signatureBuffer.Length();
496
372
 
497
- promise.set_value(EDHOC_SUCCESS);
373
+ return EDHOC_SUCCESS;
498
374
  };
499
375
 
500
- auto blockingCallHandler = [this, &context, &promise, kid, &input, input_length, signature_size, successHandler](
501
- Napi::Env env, Napi::Function jsCallback) {
502
- Napi::HandleScope scope(env);
503
- std::vector<napi_value> args = {
504
- context->parent.Value(),
505
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(kid), CONFIG_LIBEDHOC_KEY_ID_LEN),
506
- Napi::Buffer<uint8_t>::Copy(env, input, input_length),
507
- Napi::Number::New(env, static_cast<size_t>(signature_size))};
508
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
509
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
510
- errorHandler);
376
+ auto argumentsHandler = [this, &key_id, &input, input_length, signature_size](Napi::Env env) {
377
+ return std::vector<napi_value> {
378
+ this->edhocRef.Value(),
379
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
380
+ Napi::Buffer<uint8_t>::Copy(env, input, input_length),
381
+ Napi::Number::New(env, static_cast<size_t>(signature_size))
382
+ };
511
383
  };
512
384
 
513
- signTsfn.BlockingCall(blockingCallHandler);
514
-
515
- future.wait();
516
- return future.get();
385
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "sign", argumentsHandler, successHandler);
517
386
  }
518
387
 
519
- int EdhocCryptoManager::callVerify(const void* user_context,
388
+ int EdhocCryptoManager::callVerify(RunningContext* runningContext,
520
389
  const void* key_id,
521
390
  const uint8_t* input,
522
391
  size_t input_length,
523
392
  const uint8_t* signature,
524
393
  size_t signature_length) {
525
- std::promise<int> promise;
526
- std::future<int> future = promise.get_future();
527
394
 
528
- UserContext* context = static_cast<UserContext*>(const_cast<void*>(user_context));
529
-
530
- auto successHandler = [&promise, &context](Napi::Env env, Napi::Value result) {
395
+ auto successHandler = [](Napi::Env env, Napi::Value result) {
531
396
  Napi::HandleScope scope(env);
532
397
  if (!result.IsBoolean()) {
533
- context->error = Napi::Error::New(env, kErrorExpectBooleanVerify);
534
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
398
+ throw std::runtime_error(kErrorExpectBooleanVerify);
535
399
  }
536
- promise.set_value(result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_CRYPTO_FAILURE);
400
+ return result.As<Napi::Boolean>().Value() ? EDHOC_SUCCESS : EDHOC_ERROR_CRYPTO_FAILURE;
537
401
  };
538
402
 
539
- auto blockingCallHandler = [this, &context, &promise, &key_id, &input, input_length, &signature, signature_length,
540
- successHandler](Napi::Env env, Napi::Function jsCallback) {
541
- Napi::HandleScope scope(env);
542
- std::vector<napi_value> args = {
543
- context->parent.Value(),
544
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
545
- Napi::Buffer<uint8_t>::Copy(env, input, input_length),
546
- Napi::Buffer<uint8_t>::Copy(env, signature, signature_length),
403
+ auto argumentsHandler = [this, &key_id, &input, input_length, &signature, signature_length](Napi::Env env) {
404
+ return std::vector<napi_value> {
405
+ this->edhocRef.Value(),
406
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
407
+ Napi::Buffer<uint8_t>::Copy(env, input, input_length),
408
+ Napi::Buffer<uint8_t>::Copy(env, signature, signature_length)
547
409
  };
548
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
549
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
550
- errorHandler);
551
410
  };
552
411
 
553
- verifyTsfn.BlockingCall(blockingCallHandler);
554
-
555
- future.wait();
556
- return future.get();
412
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "verify", argumentsHandler, successHandler);
557
413
  }
558
414
 
559
- int EdhocCryptoManager::callExtract(const void* user_context,
415
+ int EdhocCryptoManager::callExtract(RunningContext* runningContext,
560
416
  const void* key_id,
561
417
  const uint8_t* salt,
562
418
  size_t salt_len,
563
419
  uint8_t* pseudo_random_key,
564
420
  size_t pseudo_random_key_size,
565
421
  size_t* pseudo_random_key_length) {
566
- std::promise<int> promise;
567
- std::future<int> future = promise.get_future();
568
-
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](
572
- Napi::Env env, Napi::Value result) {
422
+ auto successHandler = [&pseudo_random_key, pseudo_random_key_size, &pseudo_random_key_length](Napi::Env env, Napi::Value result) {
573
423
  Napi::HandleScope scope(env);
574
424
  if (!result.IsBuffer()) {
575
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
576
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
425
+ throw std::runtime_error(kErrorExpectBuffer);
577
426
  }
578
427
  Napi::Buffer<uint8_t> randomKeyBuffer = result.As<Napi::Buffer<uint8_t>>();
579
428
  if (randomKeyBuffer.Length() > pseudo_random_key_size) {
580
- context->error = Napi::Error::New(env, kErrorPseudoRandpmLengthExceeds);
581
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
429
+ throw std::runtime_error(kErrorPseudoRandpmLengthExceeds);
582
430
  }
583
431
  memcpy(pseudo_random_key, randomKeyBuffer.Data(), randomKeyBuffer.Length());
584
432
  *pseudo_random_key_length = randomKeyBuffer.Length();
585
433
 
586
- promise.set_value(EDHOC_SUCCESS);
434
+ return EDHOC_SUCCESS;
587
435
  };
588
436
 
589
- auto blockingCallHandler = [this, &context, &promise, &key_id, &salt, salt_len, pseudo_random_key_size,
590
- successHandler](Napi::Env env, Napi::Function jsCallback) {
591
- Napi::HandleScope scope(env);
592
- std::vector<napi_value> args = {
593
- context->parent.Value(),
594
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
595
- Napi::Buffer<uint8_t>::Copy(env, salt, salt_len),
596
- Napi::Number::New(env, static_cast<size_t>(pseudo_random_key_size))};
597
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
598
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
599
- errorHandler);
437
+ auto argumentsHandler = [this, &key_id, &salt, salt_len, pseudo_random_key_size](Napi::Env env) {
438
+ return std::vector<napi_value> {
439
+ this->edhocRef.Value(),
440
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
441
+ Napi::Buffer<uint8_t>::Copy(env, salt, salt_len),
442
+ Napi::Number::New(env, static_cast<size_t>(pseudo_random_key_size))
443
+ };
600
444
  };
601
445
 
602
- extractTsfn.BlockingCall(blockingCallHandler);
603
-
604
- future.wait();
605
- return future.get();
446
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "extract", argumentsHandler, successHandler);
606
447
  }
607
448
 
608
- int EdhocCryptoManager::callExpand(const void* user_context,
449
+ int EdhocCryptoManager::callExpand(RunningContext* runningContext,
609
450
  const void* key_id,
610
451
  const uint8_t* info,
611
452
  size_t info_length,
612
453
  uint8_t* output_keying_material,
613
454
  size_t output_keying_material_length) {
614
- std::promise<int> promise;
615
- std::future<int> future = promise.get_future();
616
-
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) {
455
+ auto successHandler = [&output_keying_material, output_keying_material_length](Napi::Env env, Napi::Value result) {
621
456
  Napi::HandleScope scope(env);
622
457
  if (!result.IsBuffer()) {
623
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
624
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
458
+ throw std::runtime_error(kErrorExpectBuffer);
625
459
  }
626
460
  Napi::Buffer<uint8_t> outputBuffer = result.As<Napi::Buffer<uint8_t>>();
627
461
  if (outputBuffer.Length() > output_keying_material_length) {
628
- context->error = Napi::Error::New(env, kErrorKeyingMaterialLengthExceeds);
629
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
462
+ throw std::runtime_error(kErrorKeyingMaterialLengthExceeds);
630
463
  }
631
464
  memcpy(output_keying_material, outputBuffer.Data(), outputBuffer.Length());
632
465
 
633
- promise.set_value(EDHOC_SUCCESS);
466
+ return EDHOC_SUCCESS;
634
467
  };
635
468
 
636
- auto blockingCallHandler = [this, &context, &promise, &key_id, &info, info_length, output_keying_material_length,
637
- successHandler](Napi::Env env, Napi::Function jsCallback) {
638
- Napi::HandleScope scope(env);
639
- std::vector<napi_value> args = {
640
- context->parent.Value(),
641
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
642
- Napi::Buffer<uint8_t>::Copy(env, info, info_length),
643
- Napi::Number::New(env, static_cast<size_t>(output_keying_material_length))};
644
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
645
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
646
- errorHandler);
469
+ auto argumentsHandler = [this, &key_id, &info, info_length, output_keying_material_length](Napi::Env env) {
470
+ return std::vector<napi_value> {
471
+ this->edhocRef.Value(),
472
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
473
+ Napi::Buffer<uint8_t>::Copy(env, info, info_length),
474
+ Napi::Number::New(env, static_cast<size_t>(output_keying_material_length))
475
+ };
647
476
  };
648
477
 
649
- expandTsfn.BlockingCall(blockingCallHandler);
650
-
651
- future.wait();
652
- return future.get();
478
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "expand", argumentsHandler, successHandler);
653
479
  }
654
480
 
655
- int EdhocCryptoManager::callEncrypt(const void* user_context,
481
+ int EdhocCryptoManager::callEncrypt(RunningContext* runningContext,
656
482
  const void* key_id,
657
483
  const uint8_t* nonce,
658
484
  size_t nonce_length,
@@ -663,52 +489,37 @@ int EdhocCryptoManager::callEncrypt(const void* user_context,
663
489
  uint8_t* ciphertext,
664
490
  size_t ciphertext_size,
665
491
  size_t* ciphertext_length) {
666
- std::promise<int> promise;
667
- std::future<int> future = promise.get_future();
668
-
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) {
492
+ auto successHandler = [&ciphertext, ciphertext_size, &ciphertext_length](Napi::Env env, Napi::Value result) {
673
493
  Napi::HandleScope scope(env);
674
494
  if (!result.IsBuffer()) {
675
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
676
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
495
+ throw std::runtime_error(kErrorExpectBuffer);
677
496
  }
678
497
  Napi::Buffer<uint8_t> ciphertextBuffer = result.As<Napi::Buffer<uint8_t>>();
679
498
  if (ciphertextBuffer.Length() > ciphertext_size) {
680
- context->error = Napi::Error::New(env, kErrorBufferTooSmall);
681
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
499
+ throw std::runtime_error(kErrorBufferTooSmall);
682
500
  }
683
501
  memcpy(ciphertext, ciphertextBuffer.Data(), ciphertextBuffer.Length());
684
502
  *ciphertext_length = ciphertextBuffer.Length();
685
503
 
686
- promise.set_value(EDHOC_SUCCESS);
504
+ return EDHOC_SUCCESS;
687
505
  };
688
506
 
689
- auto blockingCallHandler = [this, &context, &promise, &key_id, &nonce, nonce_length, &additional_data,
690
- additional_data_length, &plaintext, plaintext_length, ciphertext_size,
691
- successHandler](Napi::Env env, Napi::Function jsCallback) {
692
- Napi::HandleScope scope(env);
693
- std::vector<napi_value> args = {
694
- context->parent.Value(),
695
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
696
- Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
697
- Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
698
- Napi::Buffer<uint8_t>::Copy(env, plaintext, plaintext_length),
699
- Napi::Number::New(env, static_cast<size_t>(ciphertext_size))};
700
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
701
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, args, successHandler,
702
- errorHandler);
507
+ auto argumentsHandler = [this, &key_id, &nonce, nonce_length, &additional_data,
508
+ additional_data_length, &plaintext, plaintext_length, ciphertext_size](Napi::Env env) {
509
+ return std::vector<napi_value> {
510
+ this->edhocRef.Value(),
511
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
512
+ Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
513
+ Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
514
+ Napi::Buffer<uint8_t>::Copy(env, plaintext, plaintext_length),
515
+ Napi::Number::New(env, static_cast<size_t>(ciphertext_size))
516
+ };
703
517
  };
704
518
 
705
- encryptTsfn.BlockingCall(blockingCallHandler);
706
-
707
- future.wait();
708
- return future.get();
519
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "encrypt", argumentsHandler, successHandler);
709
520
  }
710
521
 
711
- int EdhocCryptoManager::callDecrypt(const void* user_context,
522
+ int EdhocCryptoManager::callDecrypt(RunningContext* runningContext,
712
523
  const void* key_id,
713
524
  const uint8_t* nonce,
714
525
  size_t nonce_length,
@@ -719,94 +530,64 @@ int EdhocCryptoManager::callDecrypt(const void* user_context,
719
530
  uint8_t* plaintext,
720
531
  size_t plaintext_size,
721
532
  size_t* plaintext_length) {
722
- std::promise<int> promise;
723
- std::future<int> future = promise.get_future();
724
-
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) {
533
+ auto successHandler = [&plaintext, plaintext_size, &plaintext_length](Napi::Env env, Napi::Value result) {
729
534
  Napi::HandleScope scope(env);
730
535
  if (!result.IsBuffer()) {
731
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
732
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
536
+ throw std::runtime_error(kErrorExpectBuffer);
733
537
  }
734
538
  Napi::Buffer<uint8_t> plaintextBuffer = result.As<Napi::Buffer<uint8_t>>();
735
539
  if (plaintextBuffer.Length() > plaintext_size) {
736
- context->error = Napi::Error::New(env, kErrorPlaintextLengthExceeds);
737
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
540
+ throw std::runtime_error(kErrorPlaintextLengthExceeds);
738
541
  }
739
542
  memcpy(plaintext, plaintextBuffer.Data(), plaintextBuffer.Length());
740
543
  *plaintext_length = plaintextBuffer.Length();
741
544
 
742
- promise.set_value(EDHOC_SUCCESS);
545
+ return EDHOC_SUCCESS;
743
546
  };
744
547
 
745
- auto blockingCallHandler = [this, &context, &promise, &key_id, &nonce, nonce_length, &additional_data,
746
- additional_data_length, &ciphertext, &ciphertext_length, plaintext_size,
747
- successHandler](Napi::Env env, Napi::Function jsCallback) {
748
- Napi::HandleScope scope(env);
749
- std::vector<napi_value> arguments = {
750
- context->parent.Value(),
751
- Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
752
- Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
753
- Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
754
- Napi::Buffer<uint8_t>::Copy(env, ciphertext, ciphertext_length),
755
- Napi::Number::New(env, static_cast<size_t>(plaintext_size))};
756
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
757
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, arguments, successHandler,
758
- errorHandler);
548
+ auto argumentsHandler = [this, &key_id, &nonce, nonce_length, &additional_data,
549
+ additional_data_length, &ciphertext, &ciphertext_length, plaintext_size](Napi::Env env) {
550
+ return std::vector<napi_value> {
551
+ this->edhocRef.Value(),
552
+ Napi::Buffer<uint8_t>::Copy(env, static_cast<const uint8_t*>(key_id), CONFIG_LIBEDHOC_KEY_ID_LEN),
553
+ Napi::Buffer<uint8_t>::Copy(env, nonce, nonce_length),
554
+ Napi::Buffer<uint8_t>::Copy(env, additional_data, additional_data_length),
555
+ Napi::Buffer<uint8_t>::Copy(env, ciphertext, ciphertext_length),
556
+ Napi::Number::New(env, static_cast<size_t>(plaintext_size))
557
+ };
759
558
  };
760
559
 
761
- decryptTsfn.BlockingCall(blockingCallHandler);
762
-
763
- future.wait();
764
- return future.get();
560
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "decrypt", argumentsHandler, successHandler);
765
561
  }
766
562
 
767
- int EdhocCryptoManager::callHash(const void* user_context,
563
+ int EdhocCryptoManager::callHash(RunningContext* runningContext,
768
564
  const uint8_t* input,
769
565
  size_t input_length,
770
566
  uint8_t* hash,
771
567
  size_t hash_size,
772
568
  size_t* hash_length) {
773
- std::promise<int> promise;
774
- std::future<int> future = promise.get_future();
775
-
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) {
569
+ auto successHandler = [&hash, hash_size, &hash_length](Napi::Env env, Napi::Value result) {
779
570
  Napi::HandleScope scope(env);
780
571
  if (!result.IsBuffer()) {
781
- context->error = Napi::Error::New(env, kErrorExpectBuffer);
782
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
572
+ throw std::runtime_error(kErrorExpectBuffer);
783
573
  }
784
574
  Napi::Buffer<uint8_t> hashBuffer = result.As<Napi::Buffer<uint8_t>>();
785
575
  if (hashBuffer.Length() > hash_size) {
786
- context->error = Napi::Error::New(env, kErrorHashLengthExceeds);
787
- return promise.set_value(EDHOC_ERROR_GENERIC_ERROR);
576
+ throw std::runtime_error(kErrorHashLengthExceeds);
788
577
  }
789
578
  memcpy(hash, hashBuffer.Data(), hashBuffer.Length());
790
579
  *hash_length = hashBuffer.Length();
791
580
 
792
- promise.set_value(EDHOC_SUCCESS);
581
+ return EDHOC_SUCCESS;
793
582
  };
794
583
 
795
- auto blockingCallHandler = [this, &context, &promise, &input, input_length, hash_size, successHandler](
796
- Napi::Env env, Napi::Function jsCallback) {
797
- Napi::HandleScope scope(env);
798
- std::vector<napi_value> arguments = {
799
- context->parent.Value(),
800
- Napi::Buffer<uint8_t>::Copy(env, input, input_length),
801
- Napi::Number::New(env, static_cast<size_t>(hash_size)),
584
+ auto argumentsHandler = [this, &input, input_length, hash_size](Napi::Env env) {
585
+ return std::vector<napi_value> {
586
+ this->edhocRef.Value(),
587
+ Napi::Buffer<uint8_t>::Copy(env, input, input_length),
588
+ Napi::Number::New(env, static_cast<size_t>(hash_size))
802
589
  };
803
- auto errorHandler = Utils::CreatePromiseErrorHandler<int>(promise, EDHOC_ERROR_GENERIC_ERROR, context->error);
804
- Utils::InvokeJSFunctionWithPromiseHandling(env, cryptoManagerRef.Value(), jsCallback, arguments, successHandler,
805
- errorHandler);
806
590
  };
807
591
 
808
- hashTsfn.BlockingCall(blockingCallHandler);
809
-
810
- future.wait();
811
- return future.get();
592
+ return runningContext->ThreadSafeBlockingCall(cryptoManagerRef, "hash", argumentsHandler, successHandler);
812
593
  }