edhoc 1.2.1 → 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.
@@ -11,29 +11,37 @@ EdhocKeyUpdateAsyncWorker::EdhocKeyUpdateAsyncWorker(Napi::Env& env,
11
11
  callback(std::move(callback)) {}
12
12
 
13
13
  void EdhocKeyUpdateAsyncWorker::Execute() {
14
- try {
15
- int ret = edhoc_export_key_update(&context, contextBuffer.data(), contextBuffer.size());
16
-
17
- if (ret != EDHOC_SUCCESS) {
18
- SetError("Failed to update key.");
19
- }
20
- } catch (const std::exception& e) {
21
- SetError(e.what());
14
+ int ret = edhoc_export_key_update(&context, contextBuffer.data(), contextBuffer.size());
15
+
16
+ if (ret != EDHOC_SUCCESS) {
17
+ SetError("Failed to update key.");
22
18
  }
23
19
  }
24
20
 
25
21
  void EdhocKeyUpdateAsyncWorker::OnOK() {
26
22
  Napi::Env env = Env();
27
23
  Napi::HandleScope scope(env);
28
- deferred.Resolve(env.Undefined());
24
+
29
25
  callback(env);
26
+
27
+ if (env.IsExceptionPending()) {
28
+ deferred.Reject(env.GetAndClearPendingException().Value());
29
+ } else {
30
+ deferred.Resolve(env.Undefined());
31
+ }
30
32
  }
31
33
 
32
34
  void EdhocKeyUpdateAsyncWorker::OnError(const Napi::Error& error) {
33
35
  Napi::Env env = Env();
34
36
  Napi::HandleScope scope(env);
35
- deferred.Reject(error.Value());
37
+
36
38
  callback(env);
39
+
40
+ if (env.IsExceptionPending()) {
41
+ deferred.Reject(env.GetAndClearPendingException().Value());
42
+ } else {
43
+ deferred.Reject(error.Value());
44
+ }
37
45
  }
38
46
 
39
47
  Napi::Promise EdhocKeyUpdateAsyncWorker::GetPromise() {
@@ -1,5 +1,6 @@
1
1
  #include "EdhocProcessAsyncWorker.h"
2
2
 
3
+ #include <iostream>
3
4
  static constexpr const char* kErrorInvalidMessageNumber = "Invalid message number";
4
5
  static constexpr const char* kErrorMessageFormat = "Failed to process EDHOC message %d. Error code: %d";
5
6
  static constexpr const char* kErrorWrongSelectedCipherSuiteFormat =
@@ -20,81 +21,76 @@ EdhocProcessAsyncWorker::EdhocProcessAsyncWorker(Napi::Env& env,
20
21
  peerCipherSuites() {}
21
22
 
22
23
  void EdhocProcessAsyncWorker::Execute() {
23
- try {
24
- uint8_t* message = messageBuffer.data();
25
- size_t message_length = messageBuffer.size();
26
-
27
- int ret = EDHOC_ERROR_GENERIC_ERROR;
28
- switch (messageNumber) {
29
- case EDHOC_MSG_1:
30
- ret = edhoc_message_1_process(&context, message, message_length);
31
- break;
32
- case EDHOC_MSG_2:
33
- ret = edhoc_message_2_process(&context, message, message_length);
34
- break;
35
- case EDHOC_MSG_3:
36
- ret = edhoc_message_3_process(&context, message, message_length);
37
- break;
38
- case EDHOC_MSG_4:
39
- ret = edhoc_message_4_process(&context, message, message_length);
40
- break;
41
- default:
42
- SetError(kErrorInvalidMessageNumber);
43
- return;
44
- }
24
+ uint8_t* message = messageBuffer.data();
25
+ size_t message_length = messageBuffer.size();
26
+
27
+ int ret = EDHOC_ERROR_GENERIC_ERROR;
28
+ switch (messageNumber) {
29
+ case EDHOC_MSG_1:
30
+ ret = edhoc_message_1_process(&context, message, message_length);
31
+ break;
32
+ case EDHOC_MSG_2:
33
+ ret = edhoc_message_2_process(&context, message, message_length);
34
+ break;
35
+ case EDHOC_MSG_3:
36
+ ret = edhoc_message_3_process(&context, message, message_length);
37
+ break;
38
+ case EDHOC_MSG_4:
39
+ ret = edhoc_message_4_process(&context, message, message_length);
40
+ break;
41
+ default:
42
+ SetError(kErrorInvalidMessageNumber);
43
+ return;
44
+ }
45
45
 
46
- if (ret != EDHOC_SUCCESS) {
47
- enum edhoc_error_code error_code = EDHOC_ERROR_CODE_SUCCESS;
48
- ret = edhoc_error_get_code(&context, &error_code);
49
- switch (error_code) {
50
- case EDHOC_ERROR_CODE_WRONG_SELECTED_CIPHER_SUITE: {
51
- size_t csuites_len = 0;
52
- int32_t csuites[10] = {0};
53
- size_t peer_csuites_len = 0;
54
- int32_t peer_csuites[10] = {0};
55
-
56
- ret = edhoc_error_get_cipher_suites(&context, csuites, ARRAY_SIZE(csuites), &csuites_len, peer_csuites,
57
- ARRAY_SIZE(peer_csuites), &peer_csuites_len);
58
- if (ret == EDHOC_SUCCESS) {
59
- std::string suites_str = "[";
60
- for (size_t i = 0; i < csuites_len; i++) {
61
- suites_str += std::to_string(csuites[i]);
62
- if (i < csuites_len - 1) {
63
- suites_str += ", ";
64
- }
46
+ if (ret != EDHOC_SUCCESS) {
47
+ enum edhoc_error_code error_code = EDHOC_ERROR_CODE_SUCCESS;
48
+ ret = edhoc_error_get_code(&context, &error_code);
49
+ switch (error_code) {
50
+ case EDHOC_ERROR_CODE_WRONG_SELECTED_CIPHER_SUITE: {
51
+ size_t csuites_len = 0;
52
+ int32_t csuites[10] = {0};
53
+ size_t peer_csuites_len = 0;
54
+ int32_t peer_csuites[10] = {0};
55
+
56
+ ret = edhoc_error_get_cipher_suites(&context, csuites, ARRAY_SIZE(csuites), &csuites_len, peer_csuites,
57
+ ARRAY_SIZE(peer_csuites), &peer_csuites_len);
58
+ if (ret == EDHOC_SUCCESS) {
59
+ std::string suites_str = "[";
60
+ for (size_t i = 0; i < csuites_len; i++) {
61
+ suites_str += std::to_string(csuites[i]);
62
+ if (i < csuites_len - 1) {
63
+ suites_str += ", ";
65
64
  }
66
- suites_str += "*]";
67
-
68
- std::string peer_suites_str = "[";
69
- for (size_t i = 0; i < peer_csuites_len; i++) {
70
- peer_suites_str += std::to_string(peer_csuites[i]);
71
- if (i < peer_csuites_len - 1) {
72
- peer_suites_str += ", ";
73
- }
65
+ }
66
+ suites_str += "*]";
67
+
68
+ std::string peer_suites_str = "[";
69
+ for (size_t i = 0; i < peer_csuites_len; i++) {
70
+ peer_suites_str += std::to_string(peer_csuites[i]);
71
+ if (i < peer_csuites_len - 1) {
72
+ peer_suites_str += ", ";
74
73
  }
75
- peer_suites_str += "*]";
74
+ }
75
+ peer_suites_str += "*]";
76
76
 
77
- peerCipherSuites.assign(peer_csuites, peer_csuites + peer_csuites_len);
77
+ peerCipherSuites.assign(peer_csuites, peer_csuites + peer_csuites_len);
78
78
 
79
- char errorMessage[kErrorBufferSize];
80
- std::snprintf(errorMessage, kErrorBufferSize, kErrorWrongSelectedCipherSuiteFormat, suites_str.c_str(),
81
- peer_suites_str.c_str());
82
- SetError(errorMessage);
83
- return;
84
- }
85
- break;
79
+ char errorMessage[kErrorBufferSize];
80
+ std::snprintf(errorMessage, kErrorBufferSize, kErrorWrongSelectedCipherSuiteFormat, suites_str.c_str(),
81
+ peer_suites_str.c_str());
82
+ SetError(errorMessage);
83
+ return;
86
84
  }
87
- default:
88
- break;
85
+ break;
89
86
  }
90
-
91
- char errorMessage[kErrorBufferSize];
92
- std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, messageNumber + 1, error_code);
93
- SetError(errorMessage);
87
+ default:
88
+ break;
94
89
  }
95
90
 
96
- } catch (const std::exception& e) {
97
- SetError(e.what());
91
+ char errorMessage[kErrorBufferSize];
92
+ std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, messageNumber + 1, error_code);
93
+ SetError(errorMessage);
98
94
  }
99
95
  }
100
96
 
@@ -102,8 +98,14 @@ void EdhocProcessAsyncWorker::OnOK() {
102
98
  Napi::Env env = Env();
103
99
  Napi::HandleScope scope(env);
104
100
  Napi::Array result = callback(env);
105
- deferred.Resolve(result);
101
+
106
102
  callback(env);
103
+
104
+ if (env.IsExceptionPending()) {
105
+ deferred.Reject(env.GetAndClearPendingException().Value());
106
+ } else {
107
+ deferred.Resolve(result);
108
+ }
107
109
  }
108
110
 
109
111
  void EdhocProcessAsyncWorker::OnError(const Napi::Error& error) {
@@ -118,8 +120,13 @@ void EdhocProcessAsyncWorker::OnError(const Napi::Error& error) {
118
120
  error.Set("peerCipherSuites", result);
119
121
  }
120
122
 
121
- deferred.Reject(error.Value());
122
123
  callback(env);
124
+
125
+ if (env.IsExceptionPending()) {
126
+ deferred.Reject(env.GetAndClearPendingException().Value());
127
+ } else {
128
+ deferred.Reject(error.Value());
129
+ }
123
130
  }
124
131
 
125
132
  Napi::Promise EdhocProcessAsyncWorker::GetPromise() {
package/src/LibEDHOC.cpp CHANGED
@@ -49,7 +49,7 @@ LibEDHOC::LibEDHOC(const Napi::CallbackInfo& info) : Napi::ObjectWrap<LibEDHOC>(
49
49
  // Initialize EDHOC context
50
50
  context = {};
51
51
  if (edhoc_context_init(&context) != EDHOC_SUCCESS) {
52
- throw Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext);
52
+ Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
53
53
  }
54
54
 
55
55
  // Connection ID, Methods, and Suites
@@ -72,7 +72,7 @@ LibEDHOC::LibEDHOC(const Napi::CallbackInfo& info) : Napi::ObjectWrap<LibEDHOC>(
72
72
  edhoc_bind_crypto(&context, &cryptoManager->crypto) != EDHOC_SUCCESS ||
73
73
  edhoc_bind_credentials(&context, &credentialManager->credentials) != EDHOC_SUCCESS ||
74
74
  edhoc_bind_ead(&context, &eadManager->ead) != EDHOC_SUCCESS) {
75
- throw Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext);
75
+ Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
76
76
  }
77
77
 
78
78
  // Logger
@@ -83,7 +83,7 @@ LibEDHOC::LibEDHOC(const Napi::CallbackInfo& info) : Napi::ObjectWrap<LibEDHOC>(
83
83
  userContext->parent = Reference<Napi::Object>::New(info.This().As<Napi::Object>());
84
84
 
85
85
  if (edhoc_set_user_context(&context, static_cast<void*>(userContext.get())) != EDHOC_SUCCESS) {
86
- throw Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext);
86
+ Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
87
87
  }
88
88
  }
89
89
 
@@ -121,7 +121,7 @@ void LibEDHOC::SetMethods(const Napi::CallbackInfo& info, const Napi::Value& val
121
121
  Napi::Env env = info.Env();
122
122
 
123
123
  if (!value.IsArray()) {
124
- throw Napi::TypeError::New(env, kErrorArrayMethodIndexesExpected);
124
+ Napi::TypeError::New(env, kErrorArrayMethodIndexesExpected).ThrowAsJavaScriptException();
125
125
  }
126
126
 
127
127
  const auto jsArray = value.As<Napi::Array>();
@@ -133,7 +133,7 @@ void LibEDHOC::SetMethods(const Napi::CallbackInfo& info, const Napi::Value& val
133
133
  }
134
134
 
135
135
  if (edhoc_set_methods(&context, methods.data(), methods.size()) != EDHOC_SUCCESS) {
136
- throw Napi::TypeError::New(env, kErrorFailedToSetEdhocMethod);
136
+ Napi::TypeError::New(env, kErrorFailedToSetEdhocMethod).ThrowAsJavaScriptException();
137
137
  }
138
138
  }
139
139
 
@@ -145,7 +145,7 @@ void LibEDHOC::SetCipherSuites(const Napi::CallbackInfo& info, const Napi::Value
145
145
  Napi::Env env = info.Env();
146
146
 
147
147
  if (!value.IsArray()) {
148
- throw Napi::TypeError::New(env, kErrorArraySuiteIndexesExpected);
148
+ Napi::TypeError::New(env, kErrorArraySuiteIndexesExpected).ThrowAsJavaScriptException();
149
149
  }
150
150
 
151
151
  const auto jsArray = value.As<Napi::Array>();
@@ -156,14 +156,14 @@ void LibEDHOC::SetCipherSuites(const Napi::CallbackInfo& info, const Napi::Value
156
156
  const uint32_t index = jsArray.Get(i).As<Napi::Number>().Uint32Value();
157
157
 
158
158
  if (index >= suite_pointers_count || suite_pointers[index] == nullptr) {
159
- throw Napi::RangeError::New(env, kErrorInvalidCipherSuiteIndex);
159
+ Napi::RangeError::New(env, kErrorInvalidCipherSuiteIndex).ThrowAsJavaScriptException();
160
160
  }
161
161
 
162
162
  selected_suites.push_back(*suite_pointers[index]);
163
163
  }
164
164
 
165
165
  if (edhoc_set_cipher_suites(&context, selected_suites.data(), selected_suites.size()) != 0) {
166
- throw Napi::TypeError::New(env, kErrorFailedToSetCipherSuites);
166
+ Napi::TypeError::New(env, kErrorFailedToSetCipherSuites).ThrowAsJavaScriptException();
167
167
  }
168
168
  }
169
169
 
@@ -215,12 +215,7 @@ Napi::Value LibEDHOC::ComposeMessage(const Napi::CallbackInfo& info, enum edhoc_
215
215
  Napi::HandleScope scope(env);
216
216
 
217
217
  if (info[0].IsArray()) {
218
- try {
219
- userContext->GetEadManager()->StoreEad(messageNumber, info[0].As<Napi::Array>());
220
- } catch (const Napi::Error& e) {
221
- e.ThrowAsJavaScriptException();
222
- return env.Null();
223
- }
218
+ userContext->GetEadManager()->StoreEad(messageNumber, info[0].As<Napi::Array>());
224
219
  }
225
220
 
226
221
  userContext->GetCredentialManager()->SetupAsyncFunctions();
@@ -230,6 +225,9 @@ Napi::Value LibEDHOC::ComposeMessage(const Napi::CallbackInfo& info, enum edhoc_
230
225
  userContext->GetEadManager()->ClearEadByMessage(messageNumber);
231
226
  userContext->GetCredentialManager()->CleanupAsyncFunctions();
232
227
  userContext->GetCryptoManager()->CleanupAsyncFunctions();
228
+ if (!userContext->error.IsEmpty()) {
229
+ userContext->error.ThrowAsJavaScriptException();
230
+ }
233
231
  };
234
232
 
235
233
  EdhocComposeAsyncWorker* worker = new EdhocComposeAsyncWorker(env, context, messageNumber, callback);
@@ -256,6 +254,9 @@ Napi::Value LibEDHOC::ProcessMessage(const Napi::CallbackInfo& info, enum edhoc_
256
254
  userContext->GetEadManager()->ClearEadByMessage(messageNumber);
257
255
  userContext->GetCredentialManager()->CleanupAsyncFunctions();
258
256
  userContext->GetCryptoManager()->CleanupAsyncFunctions();
257
+ if (!userContext->error.IsEmpty()) {
258
+ userContext->error.ThrowAsJavaScriptException();
259
+ }
259
260
  return EADs;
260
261
  };
261
262
 
@@ -307,6 +308,9 @@ Napi::Value LibEDHOC::ExportOSCORE(const Napi::CallbackInfo& info) {
307
308
  EdhocExportOscoreAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
308
309
  userContext->GetCredentialManager()->CleanupAsyncFunctions();
309
310
  userContext->GetCryptoManager()->CleanupAsyncFunctions();
311
+ if (!userContext->error.IsEmpty()) {
312
+ userContext->error.ThrowAsJavaScriptException();
313
+ }
310
314
  };
311
315
 
312
316
  EdhocExportOscoreAsyncWorker* worker = new EdhocExportOscoreAsyncWorker(env, context, callback);
@@ -338,6 +342,9 @@ Napi::Value LibEDHOC::ExportKey(const Napi::CallbackInfo& info) {
338
342
  EdhocKeyExporterAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
339
343
  userContext->GetCredentialManager()->CleanupAsyncFunctions();
340
344
  userContext->GetCryptoManager()->CleanupAsyncFunctions();
345
+ if (!userContext->error.IsEmpty()) {
346
+ userContext->error.ThrowAsJavaScriptException();
347
+ }
341
348
  };
342
349
 
343
350
  EdhocKeyExporterAsyncWorker* worker = new EdhocKeyExporterAsyncWorker(env, context, label, desiredLength, callback);
@@ -364,6 +371,9 @@ Napi::Value LibEDHOC::KeyUpdate(const Napi::CallbackInfo& info) {
364
371
  EdhocKeyUpdateAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
365
372
  userContext->GetCredentialManager()->CleanupAsyncFunctions();
366
373
  userContext->GetCryptoManager()->CleanupAsyncFunctions();
374
+ if (!userContext->error.IsEmpty()) {
375
+ userContext->error.ThrowAsJavaScriptException();
376
+ }
367
377
  };
368
378
 
369
379
  EdhocKeyUpdateAsyncWorker* worker = new EdhocKeyUpdateAsyncWorker(env, context, contextBufferVector, callback);
package/src/Utils.cpp CHANGED
@@ -6,7 +6,6 @@
6
6
  #include <thread>
7
7
 
8
8
  static constexpr const char* kStringThen = "then";
9
- static constexpr const char* kStringCatch = "catch";
10
9
  static constexpr const char* kErrorInputValueMustBeANumberOrABuffer = "Input value must be a number or a buffer";
11
10
 
12
11
  void Utils::InvokeJSFunctionWithPromiseHandling(Napi::Env env,
@@ -17,21 +16,18 @@ void Utils::InvokeJSFunctionWithPromiseHandling(Napi::Env env,
17
16
  ErrorHandler errorLambda) {
18
17
  auto deferred = Napi::Promise::Deferred::New(env);
19
18
 
20
- try {
21
- Napi::Value result = jsCallback.Call(jsObject, args);
19
+ Napi::Value result = jsCallback.Call(jsObject, args);
20
+
21
+ if (env.IsExceptionPending()) {
22
+ deferred.Reject(env.GetAndClearPendingException().Value());
23
+ } else {
22
24
  deferred.Resolve(result);
23
- } catch (const Napi::Error& e) {
24
- deferred.Reject(e.Value());
25
25
  }
26
26
 
27
27
  auto thenCallback = Napi::Function::New(env, [successLambda, errorLambda](const Napi::CallbackInfo& info) {
28
28
  Napi::Env env = info.Env();
29
29
  Napi::HandleScope scope(env);
30
- try {
31
- successLambda(env, info[0].As<Napi::Value>());
32
- } catch (const std::exception& e) {
33
- errorLambda(env, Napi::Error::New(env, e.what()));
34
- }
30
+ successLambda(env, info[0].As<Napi::Value>());
35
31
  });
36
32
 
37
33
  auto catchCallback = Napi::Function::New(env, [errorLambda](const Napi::CallbackInfo& info) {
@@ -41,8 +37,7 @@ void Utils::InvokeJSFunctionWithPromiseHandling(Napi::Env env,
41
37
  });
42
38
 
43
39
  Napi::Promise promise = deferred.Promise();
44
- promise.Get(kStringCatch).As<Napi::Function>().Call(promise, {catchCallback});
45
- promise.Get(kStringThen).As<Napi::Function>().Call(promise, {thenCallback});
40
+ promise.Get(kStringThen).As<Napi::Function>().Call(promise, {thenCallback, catchCallback});
46
41
  }
47
42
 
48
43
  void Utils::EncodeInt64ToBuffer(int64_t value, uint8_t* buffer, size_t* length) {
@@ -76,7 +71,7 @@ struct edhoc_connection_id Utils::ConvertJsValueToEdhocCid(Napi::Value value) {
76
71
  cid.bstr_length = buffer.Length();
77
72
  memcpy(cid.bstr_value, buffer.Data(), cid.bstr_length);
78
73
  } else {
79
- throw Napi::TypeError::New(value.Env(), kErrorInputValueMustBeANumberOrABuffer);
74
+ Napi::TypeError::New(value.Env(), kErrorInputValueMustBeANumberOrABuffer).ThrowAsJavaScriptException();
80
75
  }
81
76
  return cid;
82
77
  }
@@ -0,0 +1,129 @@
1
+ import { EDHOC, X509CertificateCredentialManager, DefaultEdhocCryptoManager, EdhocMethod, EdhocSuite } from '../dist/index'
2
+
3
+ describe('EDHOC Handshake', () => {
4
+
5
+ const trustedCA = Buffer.from('308201323081DAA003020102021478408C6EC18A1D452DAE70C726CB0192A6116DBB300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333635335A170D3235313031393138333635335A301A3118301606035504030C0F5468697320697320434120526F6F743059301306072A8648CE3D020106082A8648CE3D03010703420004B9348A8A267EF52CFDC30109A29008A2D99F6B8F78BA9EAF5D51578C06134E78CB90A073EDC2488A14174B4E2997C840C5DE7F8E35EB54A0DB6977E894D1B2CB300A06082A8648CE3D040302034700304402203B92BFEC770B0FA4E17F8F02A13CD945D914ED8123AC85C37C8C7BAA2BE3E0F102202CB2DC2EC295B5F4B7BB631ED751179C145D6B6E081559AEA38CE215369E9C31', 'hex');
6
+
7
+ let initiator: EDHOC;
8
+ let responder: EDHOC;
9
+ let uncaughtException: jest.Mock;
10
+ let initiatorCryptoManager: DefaultEdhocCryptoManager;
11
+ let responderCryptoManager: DefaultEdhocCryptoManager;
12
+
13
+ let initiatorCredentialManager: X509CertificateCredentialManager;
14
+ let responderCredentialManager: X509CertificateCredentialManager;
15
+
16
+ const testError = new Error('Test error');
17
+
18
+ beforeEach(() => {
19
+ const initiatorKeyID = Buffer.from('00000001', 'hex');
20
+ initiatorCredentialManager = new X509CertificateCredentialManager(
21
+ [Buffer.from('3082012E3081D4A003020102021453423D5145C767CDC29895C3DB590192A611EA50300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333732345A170D3235313031393138333732345A30143112301006035504030C09696E69746961746F723059301306072A8648CE3D020106082A8648CE3D03010703420004EB0EF585F3992A1653CF310BF0F0F8035267CDAB6989C8B02E7228FBD759EF6B56263259AADF087F9849E7B7651F74C3B4F144CCCF86BB6FE2FF0EF3AA5FB5DC300A06082A8648CE3D0403020349003046022100D8C3AA7C98A730B3D4862EDAB4C1474FCD9A17A9CA3FB078914A10978FE95CC40221009F5877DD4E2C635A04ED1F6F1854C87B58521BDDFF533B1076F53D456739764C', 'hex')],
22
+ initiatorKeyID
23
+ );
24
+ initiatorCredentialManager.addTrustedCA(trustedCA);
25
+
26
+ initiatorCryptoManager = new DefaultEdhocCryptoManager();
27
+ initiatorCryptoManager.addKey(initiatorKeyID, Buffer.from('DC1FBB05B6B08360CE5B9EEA08EBFBFC6766A21340641863D4C8A3F68F096337', 'hex'));
28
+
29
+ const responderKeyID = Buffer.from('00000002', 'hex');
30
+ responderCredentialManager = new X509CertificateCredentialManager(
31
+ [Buffer.from('3082012E3081D4A00302010202146648869E2608FC2E16D945C10E1F0192A6125CC0300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333735345A170D3235313031393138333735345A30143112301006035504030C09726573706F6E6465723059301306072A8648CE3D020106082A8648CE3D03010703420004161F76A7A106C9B79B7F651156B5B095E63A6101A39020F4E86DDACE61FB395E8AEF6CD9C444EE9A43DBD62DAD44FF50FE4146247D3AFD28F60DBC01FBFC573C300A06082A8648CE3D0403020349003046022100E8AD0926518CDB61E84D171700C7158FD0E72D03A117D40133ECD10F8B9F42CE022100E7E69B4C79100B3F0792F010AE11EE5DD2859C29EFC4DBCEFD41FA5CD4D3C3C9', 'hex')],
32
+ responderKeyID
33
+ );
34
+ responderCredentialManager.addTrustedCA(trustedCA);
35
+
36
+ responderCryptoManager = new DefaultEdhocCryptoManager();
37
+ responderCryptoManager.addKey(responderKeyID, Buffer.from('EE6287116FE27CDC539629DC87E12BF8EAA2229E7773AA67BC4C0FBA96E7FBB2', 'hex'));
38
+
39
+ initiator = new EDHOC(10, [EdhocMethod.Method1], [EdhocSuite.Suite2], initiatorCredentialManager, initiatorCryptoManager);
40
+ responder = new EDHOC(20, [EdhocMethod.Method2, EdhocMethod.Method0, EdhocMethod.Method1], [EdhocSuite.Suite2], responderCredentialManager, responderCryptoManager);
41
+ });
42
+
43
+ beforeEach(() => {
44
+ uncaughtException = jest.fn();
45
+ process.on('uncaughtException', err => uncaughtException(err))
46
+ });
47
+
48
+ afterEach(() => {
49
+ process.removeAllListeners('uncaughtException');
50
+ });
51
+
52
+ test('should throw uncaughtException', async () => {
53
+ const error = new Error('Test error');
54
+ process.emit('uncaughtException', error);
55
+ expect(uncaughtException).toHaveBeenCalledWith(error);
56
+ });
57
+
58
+ test('should throw from crypto manager hash', async () => {
59
+
60
+ responderCryptoManager.hash = jest.fn().mockImplementation(() => { throw testError });
61
+
62
+ try {
63
+
64
+ const message1 = await initiator.composeMessage1([{ label: 1, value: Buffer.from('Hello') }]);
65
+ await responder.processMessage1(message1);
66
+
67
+ } catch (error) {
68
+ expect(error).toBe(testError);
69
+ }
70
+
71
+ expect(uncaughtException).not.toHaveBeenCalled();
72
+ });
73
+
74
+ test('should throw from credential manager fetch', async () => {
75
+
76
+ responderCredentialManager.fetch = jest.fn().mockImplementation(() => { throw testError });
77
+ const catchHandler = jest.fn();
78
+
79
+ try {
80
+ const message1 = await initiator.composeMessage1();
81
+ await responder.processMessage1(message1);
82
+ await responder.composeMessage2();
83
+ } catch (error) {
84
+ catchHandler(error);
85
+ }
86
+
87
+ expect(catchHandler).toHaveBeenCalledWith(testError);
88
+ expect(uncaughtException).not.toHaveBeenCalled();
89
+ });
90
+
91
+ test('should throw from crypto manager importKey', async () => {
92
+
93
+ initiatorCryptoManager.importKey = jest.fn().mockImplementation(() => { throw testError });
94
+ const catchHandler = jest.fn();
95
+
96
+ try {
97
+ const message1 = await initiator.composeMessage1([{ label: 1, value: Buffer.from('Hello') }]);
98
+ await responder.processMessage1(message1);
99
+ await responder.composeMessage2();
100
+ } catch (error) {
101
+ catchHandler(error);
102
+ }
103
+
104
+ expect(catchHandler).toHaveBeenCalled();
105
+ expect(uncaughtException).not.toHaveBeenCalled();
106
+ });
107
+
108
+ test('should throw from crypto manager encrypt', async () => {
109
+
110
+ initiatorCryptoManager.encrypt = jest.fn().mockImplementation(() => { throw testError });
111
+ const catchHandler = jest.fn();
112
+
113
+ try {
114
+ const message1 = await initiator.composeMessage1([{ label: 1, value: Buffer.from('Hello') }]);
115
+ await responder.processMessage1(message1);
116
+
117
+ const message2 = await responder.composeMessage2();
118
+ await initiator.processMessage2(message2);
119
+
120
+ const message3 = await initiator.composeMessage3();
121
+ await responder.processMessage3(message3);
122
+ } catch (error) {
123
+ catchHandler(error);
124
+ }
125
+
126
+ expect(catchHandler).toHaveBeenCalled();
127
+ expect(uncaughtException).not.toHaveBeenCalled();
128
+ });
129
+ });