edhoc 1.2.2 → 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.
- package/dist/edhoc.d.ts +4 -0
- package/dist/edhoc.d.ts.map +1 -1
- package/include/{LibEDHOC.h → Binding.h} +60 -40
- package/include/EdhocComposeAsyncWorker.h +8 -22
- package/include/EdhocCredentialManager.h +9 -25
- package/include/EdhocCryptoManager.h +27 -43
- package/include/EdhocEadManager.h +3 -4
- package/include/EdhocExportOscoreAsyncWorker.h +10 -27
- package/include/EdhocKeyExporterAsyncWorker.h +8 -28
- package/include/EdhocKeyUpdateAsyncWorker.h +7 -24
- package/include/EdhocProcessAsyncWorker.h +11 -36
- package/include/RunningContext.h +102 -0
- package/include/Utils.h +0 -43
- package/package.json +1 -2
- package/prebuilds/android-arm/edhoc.armv7.node +0 -0
- package/prebuilds/android-arm64/edhoc.armv8.node +0 -0
- package/prebuilds/darwin-arm64/edhoc.node +0 -0
- package/prebuilds/darwin-x64/edhoc.node +0 -0
- package/prebuilds/linux-arm/edhoc.armv6.node +0 -0
- package/prebuilds/linux-arm/edhoc.armv7.node +0 -0
- package/prebuilds/linux-arm64/edhoc.armv8.node +0 -0
- package/prebuilds/linux-x64/edhoc.glibc.node +0 -0
- package/prebuilds/linux-x64/edhoc.musl.node +0 -0
- package/prebuilds/win32-ia32/edhoc.node +0 -0
- package/prebuilds/win32-x64/edhoc.node +0 -0
- package/src/Binding.cpp +434 -0
- package/src/EdhocComposeAsyncWorker.cpp +15 -26
- package/src/EdhocCredentialManager.cpp +50 -69
- package/src/EdhocCryptoManager.cpp +158 -332
- package/src/EdhocEadManager.cpp +11 -11
- package/src/EdhocExportOscoreAsyncWorker.cpp +18 -28
- package/src/EdhocKeyExporterAsyncWorker.cpp +11 -21
- package/src/EdhocKeyUpdateAsyncWorker.cpp +8 -18
- package/src/EdhocProcessAsyncWorker.cpp +28 -35
- package/src/RunningContext.cpp +95 -0
- package/src/Utils.cpp +1 -38
- package/test/basic.test.ts +57 -3
- package/include/UserContext.h +0 -77
- package/src/LibEDHOC.cpp +0 -408
package/src/EdhocEadManager.cpp
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#include <iostream>
|
|
6
6
|
#include <stdexcept>
|
|
7
7
|
|
|
8
|
-
#include "
|
|
8
|
+
#include "RunningContext.h"
|
|
9
9
|
#include "Utils.h"
|
|
10
10
|
|
|
11
11
|
static constexpr const char* kErrorExpectedObject = "Expected an object as element in the input array";
|
|
@@ -21,11 +21,11 @@ EdhocEadManager::EdhocEadManager() {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
EdhocEadManager::~EdhocEadManager() {
|
|
24
|
-
|
|
24
|
+
eadBuffers_.clear();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
void EdhocEadManager::StoreEad(enum edhoc_message message, int label, const std::vector<uint8_t>& ead) {
|
|
28
|
-
auto& vecOfMaps =
|
|
28
|
+
auto& vecOfMaps = eadBuffers_[message];
|
|
29
29
|
EadMap newMap;
|
|
30
30
|
newMap[label] = ead;
|
|
31
31
|
vecOfMaps.push_back(std::move(newMap));
|
|
@@ -56,8 +56,8 @@ void EdhocEadManager::StoreEad(enum edhoc_message message, const Napi::Array& ea
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const EadMapVector* EdhocEadManager::GetEadByMessage(enum edhoc_message message) const {
|
|
59
|
-
auto it =
|
|
60
|
-
return it !=
|
|
59
|
+
auto it = eadBuffers_.find(message);
|
|
60
|
+
return it != eadBuffers_.end() ? &it->second : nullptr;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
Napi::Array EdhocEadManager::GetEadByMessage(Napi::Env& env, enum edhoc_message message) const {
|
|
@@ -81,7 +81,7 @@ Napi::Array EdhocEadManager::GetEadByMessage(Napi::Env& env, enum edhoc_message
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
void EdhocEadManager::ClearEadByMessage(enum edhoc_message message) {
|
|
84
|
-
|
|
84
|
+
eadBuffers_.erase(message);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
int EdhocEadManager::ComposeEad(void* user_context,
|
|
@@ -89,7 +89,7 @@ int EdhocEadManager::ComposeEad(void* user_context,
|
|
|
89
89
|
struct edhoc_ead_token* ead_token,
|
|
90
90
|
size_t ead_token_size,
|
|
91
91
|
size_t* ead_token_len) {
|
|
92
|
-
|
|
92
|
+
RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
|
|
93
93
|
EdhocEadManager* manager = context->GetEadManager();
|
|
94
94
|
return manager->callComposeEad(message, ead_token, ead_token_size, ead_token_len);
|
|
95
95
|
}
|
|
@@ -98,7 +98,7 @@ int EdhocEadManager::ProcessEad(void* user_context,
|
|
|
98
98
|
enum edhoc_message message,
|
|
99
99
|
const struct edhoc_ead_token* ead_token,
|
|
100
100
|
size_t ead_token_size) {
|
|
101
|
-
|
|
101
|
+
RunningContext* context = static_cast<RunningContext*>(const_cast<void*>(user_context));
|
|
102
102
|
EdhocEadManager* manager = context->GetEadManager();
|
|
103
103
|
return manager->callProcessEad(message, ead_token, ead_token_size);
|
|
104
104
|
}
|
|
@@ -107,15 +107,15 @@ int EdhocEadManager::callComposeEad(enum edhoc_message message,
|
|
|
107
107
|
struct edhoc_ead_token* ead_token,
|
|
108
108
|
size_t ead_token_size,
|
|
109
109
|
size_t* ead_token_len) {
|
|
110
|
-
const EadMapVector*
|
|
111
|
-
if (!
|
|
110
|
+
const EadMapVector* eadBuffers_ = GetEadByMessage(message);
|
|
111
|
+
if (!eadBuffers_) {
|
|
112
112
|
*ead_token_len = 0;
|
|
113
113
|
return EDHOC_SUCCESS;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
size_t count = 0;
|
|
117
117
|
|
|
118
|
-
for (const auto& map : *
|
|
118
|
+
for (const auto& map : *eadBuffers_) {
|
|
119
119
|
for (const auto& [label, buffer] : map) {
|
|
120
120
|
if (count >= ead_token_size) {
|
|
121
121
|
break;
|
|
@@ -10,17 +10,13 @@ static constexpr size_t kMasterSecrectSize = 16;
|
|
|
10
10
|
static constexpr size_t kMasterSaltSize = 8;
|
|
11
11
|
static constexpr size_t kConnectionIdSize = 7;
|
|
12
12
|
|
|
13
|
-
EdhocExportOscoreAsyncWorker::EdhocExportOscoreAsyncWorker(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
masterSalt(kMasterSaltSize),
|
|
21
|
-
senderId(kConnectionIdSize),
|
|
22
|
-
recipientId(kConnectionIdSize),
|
|
23
|
-
callback(std::move(callback)) {}
|
|
13
|
+
EdhocExportOscoreAsyncWorker::EdhocExportOscoreAsyncWorker(RunningContext* runningContext)
|
|
14
|
+
: Napi::AsyncWorker(runningContext->GetEnv()),
|
|
15
|
+
runningContext_(runningContext),
|
|
16
|
+
masterSecret_(kMasterSecrectSize),
|
|
17
|
+
masterSalt_(kMasterSaltSize),
|
|
18
|
+
senderId_(kConnectionIdSize),
|
|
19
|
+
recipientId_(kConnectionIdSize) {}
|
|
24
20
|
|
|
25
21
|
EdhocExportOscoreAsyncWorker::~EdhocExportOscoreAsyncWorker() {}
|
|
26
22
|
|
|
@@ -28,17 +24,17 @@ void EdhocExportOscoreAsyncWorker::Execute() {
|
|
|
28
24
|
try {
|
|
29
25
|
size_t sender_id_length, recipient_id_length;
|
|
30
26
|
|
|
31
|
-
int ret = edhoc_export_oscore_session(
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
int ret = edhoc_export_oscore_session(runningContext_->GetEdhocContext(), masterSecret_.data(), masterSecret_.size(), masterSalt_.data(),
|
|
28
|
+
masterSalt_.size(), senderId_.data(), senderId_.size(), &sender_id_length,
|
|
29
|
+
recipientId_.data(), recipientId_.size(), &recipient_id_length);
|
|
34
30
|
|
|
35
31
|
if (ret != EDHOC_SUCCESS) {
|
|
36
32
|
char errorMessage[kErrorBufferSize];
|
|
37
33
|
std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
|
|
38
34
|
SetError(errorMessage);
|
|
39
35
|
} else {
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
senderId_.resize(sender_id_length);
|
|
37
|
+
recipientId_.resize(recipient_id_length);
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
} catch (const std::exception& e) {
|
|
@@ -50,10 +46,10 @@ void EdhocExportOscoreAsyncWorker::OnOK() {
|
|
|
50
46
|
Napi::Env env = Env();
|
|
51
47
|
Napi::HandleScope scope(env);
|
|
52
48
|
|
|
53
|
-
auto masterSecretBuffer = Napi::Buffer<uint8_t>::Copy(env,
|
|
54
|
-
auto masterSaltBuffer = Napi::Buffer<uint8_t>::Copy(env,
|
|
55
|
-
auto senderIdBuffer = Napi::Buffer<uint8_t>::Copy(env,
|
|
56
|
-
auto recipientIdBuffer = Napi::Buffer<uint8_t>::Copy(env,
|
|
49
|
+
auto masterSecretBuffer = Napi::Buffer<uint8_t>::Copy(env, masterSecret_.data(), masterSecret_.size());
|
|
50
|
+
auto masterSaltBuffer = Napi::Buffer<uint8_t>::Copy(env, masterSalt_.data(), masterSalt_.size());
|
|
51
|
+
auto senderIdBuffer = Napi::Buffer<uint8_t>::Copy(env, senderId_.data(), senderId_.size());
|
|
52
|
+
auto recipientIdBuffer = Napi::Buffer<uint8_t>::Copy(env, recipientId_.data(), recipientId_.size());
|
|
57
53
|
|
|
58
54
|
Napi::Object resultObj = Napi::Object::New(env);
|
|
59
55
|
resultObj.Set(kPropMasterSecret, masterSecretBuffer);
|
|
@@ -61,17 +57,11 @@ void EdhocExportOscoreAsyncWorker::OnOK() {
|
|
|
61
57
|
resultObj.Set(kPropSenderId, senderIdBuffer);
|
|
62
58
|
resultObj.Set(kPropRecipientId, recipientIdBuffer);
|
|
63
59
|
|
|
64
|
-
|
|
65
|
-
callback(env);
|
|
60
|
+
runningContext_->Resolve(resultObj);
|
|
66
61
|
}
|
|
67
62
|
|
|
68
63
|
void EdhocExportOscoreAsyncWorker::OnError(const Napi::Error& error) {
|
|
69
64
|
Napi::Env env = Env();
|
|
70
65
|
Napi::HandleScope scope(env);
|
|
71
|
-
|
|
72
|
-
callback(env);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
Napi::Promise EdhocExportOscoreAsyncWorker::GetPromise() {
|
|
76
|
-
return deferred.Promise();
|
|
66
|
+
runningContext_->Reject(error.Value());
|
|
77
67
|
}
|
|
@@ -3,22 +3,18 @@
|
|
|
3
3
|
static constexpr const char* kErrorMessageFormat = "Failed to export the key. Error code: %d.";
|
|
4
4
|
static constexpr size_t kErrorBufferSize = 100;
|
|
5
5
|
|
|
6
|
-
EdhocKeyExporterAsyncWorker::EdhocKeyExporterAsyncWorker(
|
|
7
|
-
struct edhoc_context& context,
|
|
6
|
+
EdhocKeyExporterAsyncWorker::EdhocKeyExporterAsyncWorker(RunningContext* runningContext,
|
|
8
7
|
uint16_t label,
|
|
9
|
-
uint8_t desiredLength
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
desiredLength(desiredLength),
|
|
16
|
-
output(desiredLength),
|
|
17
|
-
callback(std::move(callback)) {}
|
|
8
|
+
uint8_t desiredLength)
|
|
9
|
+
: Napi::AsyncWorker(runningContext->GetEnv()),
|
|
10
|
+
runningContext_(runningContext),
|
|
11
|
+
label_(label),
|
|
12
|
+
desiredLength_(desiredLength),
|
|
13
|
+
output_(desiredLength) {}
|
|
18
14
|
|
|
19
15
|
void EdhocKeyExporterAsyncWorker::Execute() {
|
|
20
16
|
try {
|
|
21
|
-
int ret = edhoc_export_prk_exporter(
|
|
17
|
+
int ret = edhoc_export_prk_exporter(runningContext_->GetEdhocContext(), label_, output_.data(), desiredLength_);
|
|
22
18
|
if (ret != EDHOC_SUCCESS) {
|
|
23
19
|
char errorMessage[kErrorBufferSize];
|
|
24
20
|
std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, ret);
|
|
@@ -32,18 +28,12 @@ void EdhocKeyExporterAsyncWorker::Execute() {
|
|
|
32
28
|
void EdhocKeyExporterAsyncWorker::OnOK() {
|
|
33
29
|
Napi::Env env = Env();
|
|
34
30
|
Napi::HandleScope scope(env);
|
|
35
|
-
auto outputBuffer = Napi::Buffer<uint8_t>::Copy(env,
|
|
36
|
-
|
|
37
|
-
callback(env);
|
|
31
|
+
auto outputBuffer = Napi::Buffer<uint8_t>::Copy(env, output_.data(), output_.size());
|
|
32
|
+
runningContext_->Resolve(outputBuffer);
|
|
38
33
|
}
|
|
39
34
|
|
|
40
35
|
void EdhocKeyExporterAsyncWorker::OnError(const Napi::Error& error) {
|
|
41
36
|
Napi::Env env = Env();
|
|
42
37
|
Napi::HandleScope scope(env);
|
|
43
|
-
|
|
44
|
-
callback(env);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
Napi::Promise EdhocKeyExporterAsyncWorker::GetPromise() {
|
|
48
|
-
return deferred.Promise();
|
|
38
|
+
runningContext_->Reject(error.Value());
|
|
49
39
|
}
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
#include "EdhocKeyUpdateAsyncWorker.h"
|
|
2
2
|
|
|
3
|
-
EdhocKeyUpdateAsyncWorker::EdhocKeyUpdateAsyncWorker(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
deferred(Napi::Promise::Deferred::New(env)),
|
|
9
|
-
context(context),
|
|
10
|
-
contextBuffer(contextBuffer),
|
|
11
|
-
callback(std::move(callback)) {}
|
|
3
|
+
EdhocKeyUpdateAsyncWorker::EdhocKeyUpdateAsyncWorker(RunningContext* runningContext,
|
|
4
|
+
std::vector<uint8_t> contextBuffer)
|
|
5
|
+
: Napi::AsyncWorker(runningContext->GetEnv()),
|
|
6
|
+
runningContext_(runningContext),
|
|
7
|
+
contextBuffer_(contextBuffer) {}
|
|
12
8
|
|
|
13
9
|
void EdhocKeyUpdateAsyncWorker::Execute() {
|
|
14
10
|
try {
|
|
15
|
-
int ret = edhoc_export_key_update(
|
|
11
|
+
int ret = edhoc_export_key_update(runningContext_->GetEdhocContext(), contextBuffer_.data(), contextBuffer_.size());
|
|
16
12
|
|
|
17
13
|
if (ret != EDHOC_SUCCESS) {
|
|
18
14
|
SetError("Failed to update key.");
|
|
@@ -25,17 +21,11 @@ void EdhocKeyUpdateAsyncWorker::Execute() {
|
|
|
25
21
|
void EdhocKeyUpdateAsyncWorker::OnOK() {
|
|
26
22
|
Napi::Env env = Env();
|
|
27
23
|
Napi::HandleScope scope(env);
|
|
28
|
-
|
|
29
|
-
callback(env);
|
|
24
|
+
runningContext_->Resolve(env.Undefined());
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
void EdhocKeyUpdateAsyncWorker::OnError(const Napi::Error& error) {
|
|
33
28
|
Napi::Env env = Env();
|
|
34
29
|
Napi::HandleScope scope(env);
|
|
35
|
-
|
|
36
|
-
callback(env);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
Napi::Promise EdhocKeyUpdateAsyncWorker::GetPromise() {
|
|
40
|
-
return deferred.Promise();
|
|
30
|
+
runningContext_->Reject(error.Value());
|
|
41
31
|
}
|
|
@@ -6,37 +6,33 @@ static constexpr const char* kErrorWrongSelectedCipherSuiteFormat =
|
|
|
6
6
|
"Wrong selected cipher suite. Supported: %s, Received: %s";
|
|
7
7
|
static constexpr size_t kErrorBufferSize = 100;
|
|
8
8
|
|
|
9
|
-
EdhocProcessAsyncWorker::EdhocProcessAsyncWorker(
|
|
10
|
-
struct edhoc_context& context,
|
|
9
|
+
EdhocProcessAsyncWorker::EdhocProcessAsyncWorker(RunningContext* runningContext,
|
|
11
10
|
int messageNumber,
|
|
12
|
-
Napi::Buffer<uint8_t> buffer
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
messageBuffer(buffer.Data(), buffer.Data() + buffer.Length()),
|
|
19
|
-
callback(std::move(callback)),
|
|
20
|
-
peerCipherSuites() {}
|
|
11
|
+
Napi::Buffer<uint8_t> buffer)
|
|
12
|
+
: Napi::AsyncWorker(runningContext->GetEnv()),
|
|
13
|
+
runningContext_(runningContext),
|
|
14
|
+
messageNumber_(messageNumber),
|
|
15
|
+
messageBuffer_(buffer.Data(), buffer.Data() + buffer.Length()),
|
|
16
|
+
peerCipherSuites_() {}
|
|
21
17
|
|
|
22
18
|
void EdhocProcessAsyncWorker::Execute() {
|
|
23
19
|
try {
|
|
24
|
-
uint8_t* message =
|
|
25
|
-
size_t message_length =
|
|
20
|
+
uint8_t* message = messageBuffer_.data();
|
|
21
|
+
size_t message_length = messageBuffer_.size();
|
|
26
22
|
|
|
27
23
|
int ret = EDHOC_ERROR_GENERIC_ERROR;
|
|
28
|
-
switch (
|
|
24
|
+
switch (messageNumber_) {
|
|
29
25
|
case EDHOC_MSG_1:
|
|
30
|
-
ret = edhoc_message_1_process(
|
|
26
|
+
ret = edhoc_message_1_process(runningContext_->GetEdhocContext(), message, message_length);
|
|
31
27
|
break;
|
|
32
28
|
case EDHOC_MSG_2:
|
|
33
|
-
ret = edhoc_message_2_process(
|
|
29
|
+
ret = edhoc_message_2_process(runningContext_->GetEdhocContext(), message, message_length);
|
|
34
30
|
break;
|
|
35
31
|
case EDHOC_MSG_3:
|
|
36
|
-
ret = edhoc_message_3_process(
|
|
32
|
+
ret = edhoc_message_3_process(runningContext_->GetEdhocContext(), message, message_length);
|
|
37
33
|
break;
|
|
38
34
|
case EDHOC_MSG_4:
|
|
39
|
-
ret = edhoc_message_4_process(
|
|
35
|
+
ret = edhoc_message_4_process(runningContext_->GetEdhocContext(), message, message_length);
|
|
40
36
|
break;
|
|
41
37
|
default:
|
|
42
38
|
SetError(kErrorInvalidMessageNumber);
|
|
@@ -45,7 +41,7 @@ void EdhocProcessAsyncWorker::Execute() {
|
|
|
45
41
|
|
|
46
42
|
if (ret != EDHOC_SUCCESS) {
|
|
47
43
|
enum edhoc_error_code error_code = EDHOC_ERROR_CODE_SUCCESS;
|
|
48
|
-
ret = edhoc_error_get_code(
|
|
44
|
+
ret = edhoc_error_get_code(runningContext_->GetEdhocContext(), &error_code);
|
|
49
45
|
switch (error_code) {
|
|
50
46
|
case EDHOC_ERROR_CODE_WRONG_SELECTED_CIPHER_SUITE: {
|
|
51
47
|
size_t csuites_len = 0;
|
|
@@ -53,7 +49,7 @@ void EdhocProcessAsyncWorker::Execute() {
|
|
|
53
49
|
size_t peer_csuites_len = 0;
|
|
54
50
|
int32_t peer_csuites[10] = {0};
|
|
55
51
|
|
|
56
|
-
ret = edhoc_error_get_cipher_suites(
|
|
52
|
+
ret = edhoc_error_get_cipher_suites(runningContext_->GetEdhocContext(), csuites, ARRAY_SIZE(csuites), &csuites_len, peer_csuites,
|
|
57
53
|
ARRAY_SIZE(peer_csuites), &peer_csuites_len);
|
|
58
54
|
if (ret == EDHOC_SUCCESS) {
|
|
59
55
|
std::string suites_str = "[";
|
|
@@ -74,7 +70,7 @@ void EdhocProcessAsyncWorker::Execute() {
|
|
|
74
70
|
}
|
|
75
71
|
peer_suites_str += "*]";
|
|
76
72
|
|
|
77
|
-
|
|
73
|
+
peerCipherSuites_.assign(peer_csuites, peer_csuites + peer_csuites_len);
|
|
78
74
|
|
|
79
75
|
char errorMessage[kErrorBufferSize];
|
|
80
76
|
std::snprintf(errorMessage, kErrorBufferSize, kErrorWrongSelectedCipherSuiteFormat, suites_str.c_str(),
|
|
@@ -89,7 +85,7 @@ void EdhocProcessAsyncWorker::Execute() {
|
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
char errorMessage[kErrorBufferSize];
|
|
92
|
-
std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat,
|
|
88
|
+
std::snprintf(errorMessage, kErrorBufferSize, kErrorMessageFormat, messageNumber_ + 1, error_code);
|
|
93
89
|
SetError(errorMessage);
|
|
94
90
|
}
|
|
95
91
|
|
|
@@ -101,27 +97,24 @@ void EdhocProcessAsyncWorker::Execute() {
|
|
|
101
97
|
void EdhocProcessAsyncWorker::OnOK() {
|
|
102
98
|
Napi::Env env = Env();
|
|
103
99
|
Napi::HandleScope scope(env);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
|
|
101
|
+
Napi::Array EADs = runningContext_->GetEadManager()->GetEadByMessage(env, static_cast<enum edhoc_message>(messageNumber_));
|
|
102
|
+
runningContext_->GetEadManager()->ClearEadByMessage(static_cast<enum edhoc_message>(messageNumber_));
|
|
103
|
+
|
|
104
|
+
runningContext_->Resolve(EADs);
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
void EdhocProcessAsyncWorker::OnError(const Napi::Error& error) {
|
|
110
108
|
Napi::Env env = Env();
|
|
111
109
|
Napi::HandleScope scope(env);
|
|
112
110
|
|
|
113
|
-
if (
|
|
114
|
-
Napi::Array result = Napi::Array::New(env,
|
|
115
|
-
for (size_t i = 0; i <
|
|
116
|
-
result.Set(i, Napi::Number::New(env,
|
|
111
|
+
if (peerCipherSuites_.size() > 0) {
|
|
112
|
+
Napi::Array result = Napi::Array::New(env, peerCipherSuites_.size());
|
|
113
|
+
for (size_t i = 0; i < peerCipherSuites_.size(); i++) {
|
|
114
|
+
result.Set(i, Napi::Number::New(env, peerCipherSuites_[i]));
|
|
117
115
|
}
|
|
118
116
|
error.Set("peerCipherSuites", result);
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
callback(env);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
Napi::Promise EdhocProcessAsyncWorker::GetPromise() {
|
|
126
|
-
return deferred.Promise();
|
|
119
|
+
runningContext_->Reject(error.Value());
|
|
127
120
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#include "RunningContext.h"
|
|
2
|
+
#include <iostream>
|
|
3
|
+
RunningContext::RunningContext(Napi::Env env,
|
|
4
|
+
struct edhoc_context* edhoc_context,
|
|
5
|
+
EdhocCryptoManager* cryptoManager,
|
|
6
|
+
EdhocEadManager* eadManager,
|
|
7
|
+
EdhocCredentialManager* credentialManager,
|
|
8
|
+
const Napi::Function& logger)
|
|
9
|
+
: edhoc_context_(edhoc_context)
|
|
10
|
+
, cryptoManager_(cryptoManager)
|
|
11
|
+
, eadManager_(eadManager)
|
|
12
|
+
, credentialManager_(credentialManager)
|
|
13
|
+
, tsfn_()
|
|
14
|
+
, deferred_(Napi::Promise::Deferred::New(env))
|
|
15
|
+
, loggerRef_(Napi::Weak(logger))
|
|
16
|
+
, isResolved_(false)
|
|
17
|
+
{
|
|
18
|
+
Napi::Function jsCallback = Napi::Function::New(env, [](const Napi::CallbackInfo& info) { return Napi::Value(); });
|
|
19
|
+
this->tsfn_ = Napi::ThreadSafeFunction::New(env, jsCallback, "jsCallback", 0, 1, this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
int RunningContext::ThreadSafeBlockingCall(
|
|
23
|
+
Napi::ObjectReference& jsObjectRef,
|
|
24
|
+
const std::string& jsFunctionName,
|
|
25
|
+
ArgumentsHandler argumentsHandler,
|
|
26
|
+
CompletionHandler completionHandler)
|
|
27
|
+
{
|
|
28
|
+
std::promise<int> promise;
|
|
29
|
+
std::future<int> future = promise.get_future();
|
|
30
|
+
|
|
31
|
+
this->tsfn_.BlockingCall(&promise, [this, &jsObjectRef, jsFunctionName, argumentsHandler, completionHandler](Napi::Env env, Napi::Function jsCallback, std::promise<int>* promise) {
|
|
32
|
+
Napi::HandleScope scope(env);
|
|
33
|
+
auto deferred = Napi::Promise::Deferred::New(env);
|
|
34
|
+
try {
|
|
35
|
+
const std::vector<napi_value> arguments = argumentsHandler(env);
|
|
36
|
+
Napi::Function jsFunction = jsObjectRef.Value().Get(jsFunctionName).As<Napi::Function>();
|
|
37
|
+
Napi::Value result = jsFunction.Call(jsObjectRef.Value(), arguments);
|
|
38
|
+
deferred.Resolve(result);
|
|
39
|
+
} catch (const Napi::Error& e) {
|
|
40
|
+
deferred.Reject(e.Value());
|
|
41
|
+
} catch (const std::exception& e) {
|
|
42
|
+
deferred.Reject(Napi::Error::New(env, e.what()).Value());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
auto thenCallback = Napi::Function::New(env, [this, promise, completionHandler](const Napi::CallbackInfo& info) {
|
|
46
|
+
Napi::Env env = info.Env();
|
|
47
|
+
Napi::HandleScope scope(env);
|
|
48
|
+
try {
|
|
49
|
+
int result = completionHandler(env, info[0].As<Napi::Value>());
|
|
50
|
+
promise->set_value(result);
|
|
51
|
+
} catch (const Napi::Error& e) {
|
|
52
|
+
this->Reject(info[0].As<Napi::Error>().Value());
|
|
53
|
+
promise->set_value(EDHOC_ERROR_GENERIC_ERROR);
|
|
54
|
+
} catch (const std::exception& e) {
|
|
55
|
+
this->Reject(Napi::Error::New(env, e.what()).Value());
|
|
56
|
+
promise->set_value(EDHOC_ERROR_GENERIC_ERROR);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
auto catchCallback = Napi::Function::New(env, [this, promise](const Napi::CallbackInfo& info) {
|
|
61
|
+
Napi::Env env = info.Env();
|
|
62
|
+
Napi::HandleScope scope(env);
|
|
63
|
+
this->Reject(info[0].As<Napi::Error>().Value());
|
|
64
|
+
promise->set_value(EDHOC_ERROR_GENERIC_ERROR);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
Napi::Promise promise_ = deferred.Promise();
|
|
68
|
+
promise_.Get("then").As<Napi::Function>().Call(promise_, { thenCallback, catchCallback });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
future.wait();
|
|
72
|
+
return future.get();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void RunningContext::Resolve(Napi::Value value) {
|
|
76
|
+
if (isResolved_) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
deferred_.Resolve(value);
|
|
80
|
+
tsfn_.Release();
|
|
81
|
+
isResolved_ = true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void RunningContext::Reject(Napi::Value value) {
|
|
85
|
+
if (isResolved_) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
deferred_.Reject(value);
|
|
89
|
+
tsfn_.Release();
|
|
90
|
+
isResolved_ = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Napi::Promise RunningContext::GetPromise() const {
|
|
94
|
+
return deferred_.Promise();
|
|
95
|
+
}
|
package/src/Utils.cpp
CHANGED
|
@@ -4,47 +4,10 @@
|
|
|
4
4
|
#include <cstring>
|
|
5
5
|
#include <mutex>
|
|
6
6
|
#include <thread>
|
|
7
|
+
#include <iostream>
|
|
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
|
-
void Utils::InvokeJSFunctionWithPromiseHandling(Napi::Env env,
|
|
13
|
-
Napi::Object jsObject,
|
|
14
|
-
Napi::Function jsCallback,
|
|
15
|
-
const std::vector<napi_value>& args,
|
|
16
|
-
SuccessHandler successLambda,
|
|
17
|
-
ErrorHandler errorLambda) {
|
|
18
|
-
auto deferred = Napi::Promise::Deferred::New(env);
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
Napi::Value result = jsCallback.Call(jsObject, args);
|
|
22
|
-
deferred.Resolve(result);
|
|
23
|
-
} catch (const Napi::Error& e) {
|
|
24
|
-
deferred.Reject(e.Value());
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
auto thenCallback = Napi::Function::New(env, [successLambda, errorLambda](const Napi::CallbackInfo& info) {
|
|
28
|
-
Napi::Env env = info.Env();
|
|
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
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
auto catchCallback = Napi::Function::New(env, [errorLambda](const Napi::CallbackInfo& info) {
|
|
38
|
-
Napi::Env env = info.Env();
|
|
39
|
-
Napi::HandleScope scope(env);
|
|
40
|
-
errorLambda(env, info[0].As<Napi::Error>());
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
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});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
11
|
void Utils::EncodeInt64ToBuffer(int64_t value, uint8_t* buffer, size_t* length) {
|
|
49
12
|
size_t idx = 0;
|
|
50
13
|
if (value == 0) {
|
package/test/basic.test.ts
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomBytes } from 'crypto';
|
|
2
|
+
import { EDHOC, X509CertificateCredentialManager, DefaultEdhocCryptoManager, EdhocMethod, EdhocSuite, EdhocKeyType } from '../dist/index'
|
|
2
3
|
|
|
3
4
|
describe('EDHOC Handshake', () => {
|
|
4
5
|
// Test setup variables
|
|
5
6
|
const trustedCA = Buffer.from('308201323081DAA003020102021478408C6EC18A1D452DAE70C726CB0192A6116DBB300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333635335A170D3235313031393138333635335A301A3118301606035504030C0F5468697320697320434120526F6F743059301306072A8648CE3D020106082A8648CE3D03010703420004B9348A8A267EF52CFDC30109A29008A2D99F6B8F78BA9EAF5D51578C06134E78CB90A073EDC2488A14174B4E2997C840C5DE7F8E35EB54A0DB6977E894D1B2CB300A06082A8648CE3D040302034700304402203B92BFEC770B0FA4E17F8F02A13CD945D914ED8123AC85C37C8C7BAA2BE3E0F102202CB2DC2EC295B5F4B7BB631ED751179C145D6B6E081559AEA38CE215369E9C31', 'hex');
|
|
6
7
|
let initiator: EDHOC;
|
|
7
8
|
let responder: EDHOC;
|
|
9
|
+
|
|
10
|
+
let staticDhKeyInitiator: Buffer;
|
|
11
|
+
let staticDhKeyResponder: Buffer;
|
|
12
|
+
|
|
13
|
+
let initiatorCredentialManager: X509CertificateCredentialManager;
|
|
14
|
+
let responderCredentialManager: X509CertificateCredentialManager;
|
|
15
|
+
|
|
16
|
+
class StaticCryptoManager extends DefaultEdhocCryptoManager {
|
|
17
|
+
|
|
18
|
+
async importKey(edhoc: EDHOC, keyType: EdhocKeyType, key: Buffer) {
|
|
19
|
+
if (keyType === EdhocKeyType.MakeKeyPair && key && edhoc.connectionID === 10) {
|
|
20
|
+
key = staticDhKeyInitiator
|
|
21
|
+
}
|
|
22
|
+
if (keyType === EdhocKeyType.MakeKeyPair && key && edhoc.connectionID === 20) {
|
|
23
|
+
key = staticDhKeyResponder
|
|
24
|
+
}
|
|
25
|
+
return super.importKey(edhoc, keyType, key);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
beforeAll(() => {
|
|
30
|
+
staticDhKeyInitiator = randomBytes(32);
|
|
31
|
+
staticDhKeyResponder = randomBytes(32);
|
|
32
|
+
})
|
|
8
33
|
|
|
9
34
|
beforeEach(() => {
|
|
10
35
|
// Initialize credentials and crypto managers for both parties
|
|
11
36
|
const initiatorKeyID = Buffer.from('00000001', 'hex');
|
|
12
|
-
|
|
37
|
+
initiatorCredentialManager = new X509CertificateCredentialManager(
|
|
13
38
|
[Buffer.from('3082012E3081D4A003020102021453423D5145C767CDC29895C3DB590192A611EA50300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333732345A170D3235313031393138333732345A30143112301006035504030C09696E69746961746F723059301306072A8648CE3D020106082A8648CE3D03010703420004EB0EF585F3992A1653CF310BF0F0F8035267CDAB6989C8B02E7228FBD759EF6B56263259AADF087F9849E7B7651F74C3B4F144CCCF86BB6FE2FF0EF3AA5FB5DC300A06082A8648CE3D0403020349003046022100D8C3AA7C98A730B3D4862EDAB4C1474FCD9A17A9CA3FB078914A10978FE95CC40221009F5877DD4E2C635A04ED1F6F1854C87B58521BDDFF533B1076F53D456739764C', 'hex')],
|
|
14
39
|
initiatorKeyID
|
|
15
40
|
);
|
|
@@ -19,7 +44,7 @@ describe('EDHOC Handshake', () => {
|
|
|
19
44
|
initiatorCryptoManager.addKey(initiatorKeyID, Buffer.from('DC1FBB05B6B08360CE5B9EEA08EBFBFC6766A21340641863D4C8A3F68F096337', 'hex'));
|
|
20
45
|
|
|
21
46
|
const responderKeyID = Buffer.from('00000002', 'hex');
|
|
22
|
-
|
|
47
|
+
responderCredentialManager = new X509CertificateCredentialManager(
|
|
23
48
|
[Buffer.from('3082012E3081D4A00302010202146648869E2608FC2E16D945C10E1F0192A6125CC0300A06082A8648CE3D040302301A3118301606035504030C0F5468697320697320434120526F6F74301E170D3234313031393138333735345A170D3235313031393138333735345A30143112301006035504030C09726573706F6E6465723059301306072A8648CE3D020106082A8648CE3D03010703420004161F76A7A106C9B79B7F651156B5B095E63A6101A39020F4E86DDACE61FB395E8AEF6CD9C444EE9A43DBD62DAD44FF50FE4146247D3AFD28F60DBC01FBFC573C300A06082A8648CE3D0403020349003046022100E8AD0926518CDB61E84D171700C7158FD0E72D03A117D40133ECD10F8B9F42CE022100E7E69B4C79100B3F0792F010AE11EE5DD2859C29EFC4DBCEFD41FA5CD4D3C3C9', 'hex')],
|
|
24
49
|
responderKeyID
|
|
25
50
|
);
|
|
@@ -61,4 +86,33 @@ describe('EDHOC Handshake', () => {
|
|
|
61
86
|
const responderKey = await responder.exportKey(40001, 32);
|
|
62
87
|
expect(initiatorKey).toEqual(responderKey);
|
|
63
88
|
});
|
|
89
|
+
|
|
90
|
+
test('should fail to generate message 1 twice', async () => {
|
|
91
|
+
await initiator.composeMessage1();
|
|
92
|
+
await expect(initiator.composeMessage1()).rejects.toThrow();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('should NOT fail to generate message 1 twice', () => {
|
|
96
|
+
|
|
97
|
+
it('messages should be different', async () => {
|
|
98
|
+
const message_a = await responder.composeMessage1();
|
|
99
|
+
await responder.reset();
|
|
100
|
+
const message_b = await responder.composeMessage1();
|
|
101
|
+
expect(message_a).not.toEqual(message_b);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('messages should be the same', async () => {
|
|
105
|
+
const initiatorCryptoManager = new StaticCryptoManager();
|
|
106
|
+
const responderCryptoManager = new StaticCryptoManager();
|
|
107
|
+
|
|
108
|
+
initiator = new EDHOC(10, [EdhocMethod.Method1], [EdhocSuite.Suite2], initiatorCredentialManager, initiatorCryptoManager);
|
|
109
|
+
responder = new EDHOC(20, [EdhocMethod.Method2, EdhocMethod.Method0, EdhocMethod.Method1], [EdhocSuite.Suite2], responderCredentialManager, responderCryptoManager);
|
|
110
|
+
|
|
111
|
+
const message_a = await responder.composeMessage1();
|
|
112
|
+
await responder.reset();
|
|
113
|
+
const message_b = await responder.composeMessage1();
|
|
114
|
+
|
|
115
|
+
expect(message_a).toEqual(message_b);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
64
118
|
});
|