edhoc 1.2.3 → 1.3.1

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
package/src/Utils.cpp CHANGED
@@ -4,42 +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
9
  static constexpr const char* kErrorInputValueMustBeANumberOrABuffer = "Input value must be a number or a buffer";
10
10
 
11
- void Utils::InvokeJSFunctionWithPromiseHandling(Napi::Env env,
12
- Napi::Object jsObject,
13
- Napi::Function jsCallback,
14
- const std::vector<napi_value>& args,
15
- SuccessHandler successLambda,
16
- ErrorHandler errorLambda) {
17
- auto deferred = Napi::Promise::Deferred::New(env);
18
-
19
- Napi::Value result = jsCallback.Call(jsObject, args);
20
-
21
- if (env.IsExceptionPending()) {
22
- deferred.Reject(env.GetAndClearPendingException().Value());
23
- } else {
24
- deferred.Resolve(result);
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
- successLambda(env, info[0].As<Napi::Value>());
31
- });
32
-
33
- auto catchCallback = Napi::Function::New(env, [errorLambda](const Napi::CallbackInfo& info) {
34
- Napi::Env env = info.Env();
35
- Napi::HandleScope scope(env);
36
- errorLambda(env, info[0].As<Napi::Error>());
37
- });
38
-
39
- Napi::Promise promise = deferred.Promise();
40
- promise.Get(kStringThen).As<Napi::Function>().Call(promise, {thenCallback, catchCallback});
41
- }
42
-
43
11
  void Utils::EncodeInt64ToBuffer(int64_t value, uint8_t* buffer, size_t* length) {
44
12
  size_t idx = 0;
45
13
  if (value == 0) {
@@ -71,7 +39,7 @@ struct edhoc_connection_id Utils::ConvertJsValueToEdhocCid(Napi::Value value) {
71
39
  cid.bstr_length = buffer.Length();
72
40
  memcpy(cid.bstr_value, buffer.Data(), cid.bstr_length);
73
41
  } else {
74
- Napi::TypeError::New(value.Env(), kErrorInputValueMustBeANumberOrABuffer).ThrowAsJavaScriptException();
42
+ throw Napi::TypeError::New(value.Env(), kErrorInputValueMustBeANumberOrABuffer);
75
43
  }
76
44
  return cid;
77
45
  }
@@ -1,15 +1,40 @@
1
- import { EDHOC, X509CertificateCredentialManager, DefaultEdhocCryptoManager, EdhocMethod, EdhocSuite } from '../dist/index'
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
- const initiatorCredentialManager = new X509CertificateCredentialManager(
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
- const responderCredentialManager = new X509CertificateCredentialManager(
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
  });
@@ -1,78 +0,0 @@
1
- #ifndef USER_CONTEXT_H
2
- #define USER_CONTEXT_H
3
-
4
- #include <napi.h>
5
-
6
- #include <memory>
7
-
8
- #include "EdhocCredentialManager.h"
9
- #include "EdhocCryptoManager.h"
10
- #include "EdhocEadManager.h"
11
-
12
- /**
13
- * @class UserContext
14
- * @brief Represents the user context for the Edhoc protocol.
15
- *
16
- * The UserContext class encapsulates the necessary components for the Edhoc
17
- * protocol, including the crypto manager, EAD manager, and credential manager.
18
- * It also provides access to a logger and a parent object reference.
19
- */
20
- class UserContext {
21
- public:
22
- /**
23
- * @brief Constructs a UserContext object with the specified components.
24
- *
25
- * @param cryptoManager The shared pointer to the EdhocCryptoManager.
26
- * @param eadManager The shared pointer to the EdhocEadManager.
27
- * @param credentialManager The shared pointer to the EdhocCredentialManager.
28
- */
29
- UserContext(std::shared_ptr<EdhocCryptoManager> cryptoManager,
30
- std::shared_ptr<EdhocEadManager> eadManager,
31
- std::shared_ptr<EdhocCredentialManager> credentialManager)
32
- : cryptoManager(std::move(cryptoManager)),
33
- eadManager(std::move(eadManager)),
34
- credentialManager(std::move(credentialManager)) {}
35
-
36
- /**
37
- * @brief Destroys the UserContext object.
38
- *
39
- * If a logger is present, it will be released.
40
- */
41
- virtual ~UserContext() {
42
- if (logger) {
43
- logger.Release();
44
- }
45
- }
46
-
47
- /**
48
- * @brief Gets the crypto manager associated with the UserContext.
49
- *
50
- * @return A pointer to the EdhocCryptoManager.
51
- */
52
- EdhocCryptoManager* GetCryptoManager() const { return cryptoManager.get(); }
53
-
54
- /**
55
- * @brief Gets the EAD manager associated with the UserContext.
56
- *
57
- * @return A pointer to the EdhocEadManager.
58
- */
59
- EdhocEadManager* GetEadManager() const { return eadManager.get(); }
60
-
61
- /**
62
- * @brief Gets the credential manager associated with the UserContext.
63
- *
64
- * @return A pointer to the EdhocCredentialManager.
65
- */
66
- EdhocCredentialManager* GetCredentialManager() const { return credentialManager.get(); }
67
-
68
- Napi::ThreadSafeFunction logger; ///< The logger for the UserContext
69
- Napi::ObjectReference parent; ///< The parent object reference for the UserContext
70
- Napi::Error error; ///< The last error for the UserContext
71
-
72
- protected:
73
- std::shared_ptr<EdhocCryptoManager> cryptoManager; ///< The crypto manager
74
- std::shared_ptr<EdhocEadManager> eadManager; ///< The EAD manager
75
- std::shared_ptr<EdhocCredentialManager> credentialManager; ///< The credential manager
76
- };
77
-
78
- #endif // USER_CONTEXT_H
package/src/LibEDHOC.cpp DELETED
@@ -1,418 +0,0 @@
1
- #include "LibEDHOC.h"
2
-
3
- #include <iostream>
4
- #include <thread>
5
-
6
- #include "EdhocComposeAsyncWorker.h"
7
- #include "EdhocExportOscoreAsyncWorker.h"
8
- #include "EdhocKeyExporterAsyncWorker.h"
9
- #include "EdhocKeyUpdateAsyncWorker.h"
10
- #include "EdhocProcessAsyncWorker.h"
11
- #include "Suites.h"
12
- #include "Utils.h"
13
-
14
- static constexpr const char* kErrorFailedToInitializeEdhocContext = "Failed to initialize EDHOC context.";
15
- static constexpr const char* kErrorFailedToSetEdhocConnectionId = "Failed to set EDHOC Connection ID.";
16
- static constexpr const char* kErrorFailedToSetEdhocMethod = "Failed to set EDHOC Method.";
17
- static constexpr const char* kErrorArraySuiteIndexesExpected = "Array of suite indexes expected";
18
- static constexpr const char* kErrorArrayMethodIndexesExpected = "Array of method indexes expected";
19
- static constexpr const char* kErrorInvalidCipherSuiteIndex = "Invalid cipher suite index";
20
- static constexpr const char* kErrorFailedToSetCipherSuites = "Failed to set cipher suites";
21
- static constexpr const char* kErrorExpectedFirstArgumentToBeBuffer = "Expected first argument to be a Buffer";
22
- static constexpr const char* kErrorExpectedArgumentToBeNumber = "Expected argument to be a number";
23
- static constexpr const char* kErrorExpectedAFunction = "Expected a function";
24
- static constexpr const char* kClassNameLibEDHOC = "EDHOC";
25
- static constexpr const char* kMethodComposeMessage1 = "composeMessage1";
26
- static constexpr const char* kMethodProcessMessage1 = "processMessage1";
27
- static constexpr const char* kMethodComposeMessage2 = "composeMessage2";
28
- static constexpr const char* kMethodProcessMessage2 = "processMessage2";
29
- static constexpr const char* kMethodComposeMessage3 = "composeMessage3";
30
- static constexpr const char* kMethodProcessMessage3 = "processMessage3";
31
- static constexpr const char* kMethodComposeMessage4 = "composeMessage4";
32
- static constexpr const char* kMethodProcessMessage4 = "processMessage4";
33
- static constexpr const char* kMethodExportOSCORE = "exportOSCORE";
34
- static constexpr const char* kMethodExportKey = "exportKey";
35
- static constexpr const char* kMethodKeyUpdate = "keyUpdate";
36
- static constexpr const char* kJsPropertyConnectionID = "connectionID";
37
- static constexpr const char* kJsPropertyPeerConnectionID = "peerConnectionID";
38
- static constexpr const char* kJsPropertyMethods = "methods";
39
- static constexpr const char* kJsPropertySelectedMethod = "selectedMethod";
40
- static constexpr const char* kJsPropertyCipherSuites = "cipherSuites";
41
- static constexpr const char* kJsPropertySelectedCipherSuite = "selectedSuite";
42
- static constexpr const char* kJsPropertyLogger = "logger";
43
- static constexpr const char* kLogggerFunctionName = "Logger";
44
-
45
- LibEDHOC::LibEDHOC(const Napi::CallbackInfo& info) : Napi::ObjectWrap<LibEDHOC>(info) {
46
- Napi::Env env = info.Env();
47
- Napi::HandleScope scope(env);
48
-
49
- // Initialize EDHOC context
50
- context = {};
51
- if (edhoc_context_init(&context) != EDHOC_SUCCESS) {
52
- Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
53
- }
54
-
55
- // Connection ID, Methods, and Suites
56
- SetCID(info, info[0]);
57
- SetMethods(info, info[1]);
58
- SetCipherSuites(info, info[2]);
59
-
60
- // Crypto Manager
61
- Napi::Object jsCryptoManager = info[4].As<Napi::Object>();
62
- auto cryptoManager = std::make_shared<EdhocCryptoManager>(jsCryptoManager);
63
-
64
- // Credentials
65
- Napi::Object jsCredentialManager = info[3].As<Napi::Object>();
66
- auto credentialManager = std::make_shared<EdhocCredentialManager>(jsCredentialManager);
67
- // EAD
68
- auto eadManager = std::make_shared<EdhocEadManager>();
69
-
70
- // Bind all managers
71
- if (edhoc_bind_keys(&context, &cryptoManager->keys) != EDHOC_SUCCESS ||
72
- edhoc_bind_crypto(&context, &cryptoManager->crypto) != EDHOC_SUCCESS ||
73
- edhoc_bind_credentials(&context, &credentialManager->credentials) != EDHOC_SUCCESS ||
74
- edhoc_bind_ead(&context, &eadManager->ead) != EDHOC_SUCCESS) {
75
- Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
76
- }
77
-
78
- // Logger
79
- context.logger = LibEDHOC::Logger;
80
-
81
- // User Context
82
- userContext = std::make_shared<UserContext>(cryptoManager, eadManager, credentialManager);
83
- userContext->parent = Reference<Napi::Object>::New(info.This().As<Napi::Object>());
84
-
85
- if (edhoc_set_user_context(&context, static_cast<void*>(userContext.get())) != EDHOC_SUCCESS) {
86
- Napi::TypeError::New(env, kErrorFailedToInitializeEdhocContext).ThrowAsJavaScriptException();
87
- }
88
- }
89
-
90
- LibEDHOC::~LibEDHOC() {
91
- userContext.reset();
92
- context = {};
93
- }
94
-
95
- Napi::Value LibEDHOC::GetCID(const Napi::CallbackInfo& info) {
96
- return Utils::CreateJsValueFromEdhocCid(info.Env(), cid);
97
- }
98
-
99
- void LibEDHOC::SetCID(const Napi::CallbackInfo& info, const Napi::Value& value) {
100
- cid = Utils::ConvertJsValueToEdhocCid(value);
101
- int result = edhoc_set_connection_id(&context, &cid);
102
- if (result != EDHOC_SUCCESS) {
103
- Napi::TypeError::New(info.Env(), kErrorFailedToSetEdhocConnectionId).ThrowAsJavaScriptException();
104
- }
105
- }
106
-
107
- Napi::Value LibEDHOC::GetPeerCID(const Napi::CallbackInfo& info) {
108
- return Utils::CreateJsValueFromEdhocCid(info.Env(), context.EDHOC_PRIVATE(peer_cid));
109
- }
110
-
111
- Napi::Value LibEDHOC::GetMethods(const Napi::CallbackInfo& info) {
112
- Napi::Env env = info.Env();
113
- Napi::Array result = Napi::Array::New(env, context.EDHOC_PRIVATE(method_len));
114
- for (size_t i = 0; i < context.EDHOC_PRIVATE(method_len); i++) {
115
- result.Set(i, Napi::Number::New(env, context.EDHOC_PRIVATE(method)[i]));
116
- }
117
- return result;
118
- }
119
-
120
- void LibEDHOC::SetMethods(const Napi::CallbackInfo& info, const Napi::Value& value) {
121
- Napi::Env env = info.Env();
122
-
123
- if (!value.IsArray()) {
124
- Napi::TypeError::New(env, kErrorArrayMethodIndexesExpected).ThrowAsJavaScriptException();
125
- }
126
-
127
- const auto jsArray = value.As<Napi::Array>();
128
- std::vector<edhoc_method> methods;
129
- methods.reserve(jsArray.Length());
130
-
131
- for (uint32_t i = 0; i < jsArray.Length(); i++) {
132
- methods.push_back(static_cast<edhoc_method>(jsArray.Get(i).As<Napi::Number>().Int32Value()));
133
- }
134
-
135
- if (edhoc_set_methods(&context, methods.data(), methods.size()) != EDHOC_SUCCESS) {
136
- Napi::TypeError::New(env, kErrorFailedToSetEdhocMethod).ThrowAsJavaScriptException();
137
- }
138
- }
139
-
140
- Napi::Value LibEDHOC::GetSelectedMethod(const Napi::CallbackInfo& info) {
141
- return Napi::Number::New(info.Env(), context.EDHOC_PRIVATE(chosen_method));
142
- }
143
-
144
- void LibEDHOC::SetCipherSuites(const Napi::CallbackInfo& info, const Napi::Value& value) {
145
- Napi::Env env = info.Env();
146
-
147
- if (!value.IsArray()) {
148
- Napi::TypeError::New(env, kErrorArraySuiteIndexesExpected).ThrowAsJavaScriptException();
149
- }
150
-
151
- const auto jsArray = value.As<Napi::Array>();
152
- std::vector<edhoc_cipher_suite> selected_suites;
153
- selected_suites.reserve(jsArray.Length());
154
-
155
- for (uint32_t i = 0; i < jsArray.Length(); i++) {
156
- const uint32_t index = jsArray.Get(i).As<Napi::Number>().Uint32Value();
157
-
158
- if (index >= suite_pointers_count || suite_pointers[index] == nullptr) {
159
- Napi::RangeError::New(env, kErrorInvalidCipherSuiteIndex).ThrowAsJavaScriptException();
160
- }
161
-
162
- selected_suites.push_back(*suite_pointers[index]);
163
- }
164
-
165
- if (edhoc_set_cipher_suites(&context, selected_suites.data(), selected_suites.size()) != 0) {
166
- Napi::TypeError::New(env, kErrorFailedToSetCipherSuites).ThrowAsJavaScriptException();
167
- }
168
- }
169
-
170
- Napi::Value LibEDHOC::GetCipherSuites(const Napi::CallbackInfo& info) {
171
- Napi::Env env = info.Env();
172
- Napi::Array result = Napi::Array::New(env, context.EDHOC_PRIVATE(csuite_len));
173
- for (size_t i = 0; i < context.EDHOC_PRIVATE(csuite_len); i++) {
174
- result.Set(i, Napi::Number::New(env, context.EDHOC_PRIVATE(csuite)[i].value));
175
- }
176
- return result;
177
- }
178
-
179
- Napi::Value LibEDHOC::GetSelectedCipherSuite(const Napi::CallbackInfo& info) {
180
- Napi::Env env = info.Env();
181
- Napi::Number suite =
182
- Napi::Number::New(env, context.EDHOC_PRIVATE(csuite)[context.EDHOC_PRIVATE(chosen_csuite_idx)].value);
183
- return suite;
184
- }
185
-
186
- Napi::Value LibEDHOC::GetLogger(const Napi::CallbackInfo& info) {
187
- return logger.Value();
188
- }
189
-
190
- void LibEDHOC::SetLogger(const Napi::CallbackInfo& info, const Napi::Value& value) {
191
- if (!info[0].IsFunction()) {
192
- Napi::TypeError::New(info.Env(), kErrorExpectedAFunction).ThrowAsJavaScriptException();
193
- }
194
- Napi::Function jsCallback = info[0].As<Napi::Function>();
195
- logger = Napi::Persistent(jsCallback);
196
- userContext->logger = Napi::ThreadSafeFunction::New(info.Env(), jsCallback, kLogggerFunctionName, 0, 1);
197
- }
198
-
199
- void LibEDHOC::Logger(void* usercontext, const char* name, const uint8_t* buffer, size_t buffer_length) {
200
- auto* context = static_cast<UserContext*>(usercontext);
201
- if (!context || !context->logger) {
202
- return;
203
- }
204
-
205
- const std::vector<uint8_t> bufferCopy(buffer, buffer + buffer_length);
206
-
207
- context->logger.NonBlockingCall([name = std::string(name), bufferCopy](Napi::Env env, Napi::Function jsCallback) {
208
- jsCallback.Call(
209
- {Napi::String::New(env, name), Napi::Buffer<uint8_t>::Copy(env, bufferCopy.data(), bufferCopy.size())});
210
- });
211
- }
212
-
213
- Napi::Value LibEDHOC::ComposeMessage(const Napi::CallbackInfo& info, enum edhoc_message messageNumber) {
214
- Napi::Env env = info.Env();
215
- Napi::HandleScope scope(env);
216
-
217
- if (info[0].IsArray()) {
218
- userContext->GetEadManager()->StoreEad(messageNumber, info[0].As<Napi::Array>());
219
- }
220
-
221
- userContext->GetCredentialManager()->SetupAsyncFunctions();
222
- userContext->GetCryptoManager()->SetupAsyncFunctions();
223
-
224
- EdhocComposeAsyncWorker::CallbackType callback = [this, messageNumber](Napi::Env& env) {
225
- userContext->GetEadManager()->ClearEadByMessage(messageNumber);
226
- userContext->GetCredentialManager()->CleanupAsyncFunctions();
227
- userContext->GetCryptoManager()->CleanupAsyncFunctions();
228
- if (!userContext->error.IsEmpty()) {
229
- userContext->error.ThrowAsJavaScriptException();
230
- }
231
- };
232
-
233
- EdhocComposeAsyncWorker* worker = new EdhocComposeAsyncWorker(env, context, messageNumber, callback);
234
- worker->Queue();
235
-
236
- return worker->GetPromise();
237
- }
238
-
239
- Napi::Value LibEDHOC::ProcessMessage(const Napi::CallbackInfo& info, enum edhoc_message messageNumber) {
240
- Napi::Env env = info.Env();
241
- Napi::HandleScope scope(env);
242
-
243
- if (info.Length() < 1 || !info[0].IsBuffer()) {
244
- Napi::TypeError::New(env, kErrorExpectedFirstArgumentToBeBuffer).ThrowAsJavaScriptException();
245
- return env.Null();
246
- }
247
- Napi::Buffer<uint8_t> inputBuffer = info[0].As<Napi::Buffer<uint8_t>>();
248
-
249
- userContext->GetCredentialManager()->SetupAsyncFunctions();
250
- userContext->GetCryptoManager()->SetupAsyncFunctions();
251
-
252
- EdhocProcessAsyncWorker::CallbackType callback = [this, messageNumber](Napi::Env& env) {
253
- Napi::Array EADs = userContext->GetEadManager()->GetEadByMessage(env, messageNumber);
254
- userContext->GetEadManager()->ClearEadByMessage(messageNumber);
255
- userContext->GetCredentialManager()->CleanupAsyncFunctions();
256
- userContext->GetCryptoManager()->CleanupAsyncFunctions();
257
- if (!userContext->error.IsEmpty()) {
258
- userContext->error.ThrowAsJavaScriptException();
259
- }
260
- return EADs;
261
- };
262
-
263
- EdhocProcessAsyncWorker* worker = new EdhocProcessAsyncWorker(env, context, messageNumber, inputBuffer, callback);
264
- worker->Queue();
265
-
266
- return worker->GetPromise();
267
- }
268
-
269
- Napi::Value LibEDHOC::ComposeMessage1(const Napi::CallbackInfo& info) {
270
- return ComposeMessage(info, EDHOC_MSG_1);
271
- }
272
-
273
- Napi::Value LibEDHOC::ProcessMessage1(const Napi::CallbackInfo& info) {
274
- return ProcessMessage(info, EDHOC_MSG_1);
275
- }
276
-
277
- Napi::Value LibEDHOC::ComposeMessage2(const Napi::CallbackInfo& info) {
278
- return ComposeMessage(info, EDHOC_MSG_2);
279
- }
280
-
281
- Napi::Value LibEDHOC::ProcessMessage2(const Napi::CallbackInfo& info) {
282
- return ProcessMessage(info, EDHOC_MSG_2);
283
- }
284
-
285
- Napi::Value LibEDHOC::ComposeMessage3(const Napi::CallbackInfo& info) {
286
- return ComposeMessage(info, EDHOC_MSG_3);
287
- }
288
-
289
- Napi::Value LibEDHOC::ProcessMessage3(const Napi::CallbackInfo& info) {
290
- return ProcessMessage(info, EDHOC_MSG_3);
291
- }
292
-
293
- Napi::Value LibEDHOC::ComposeMessage4(const Napi::CallbackInfo& info) {
294
- return ComposeMessage(info, EDHOC_MSG_4);
295
- }
296
-
297
- Napi::Value LibEDHOC::ProcessMessage4(const Napi::CallbackInfo& info) {
298
- return ProcessMessage(info, EDHOC_MSG_4);
299
- }
300
-
301
- Napi::Value LibEDHOC::ExportOSCORE(const Napi::CallbackInfo& info) {
302
- Napi::Env env = info.Env();
303
- Napi::HandleScope scope(env);
304
-
305
- userContext->GetCredentialManager()->SetupAsyncFunctions();
306
- userContext->GetCryptoManager()->SetupAsyncFunctions();
307
-
308
- EdhocExportOscoreAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
309
- userContext->GetCredentialManager()->CleanupAsyncFunctions();
310
- userContext->GetCryptoManager()->CleanupAsyncFunctions();
311
- if (!userContext->error.IsEmpty()) {
312
- userContext->error.ThrowAsJavaScriptException();
313
- }
314
- };
315
-
316
- EdhocExportOscoreAsyncWorker* worker = new EdhocExportOscoreAsyncWorker(env, context, callback);
317
- worker->Queue();
318
-
319
- return worker->GetPromise();
320
- }
321
-
322
- Napi::Value LibEDHOC::ExportKey(const Napi::CallbackInfo& info) {
323
- Napi::Env env = info.Env();
324
- Napi::HandleScope scope(env);
325
-
326
- if (info.Length() < 1 || !info[0].IsNumber()) {
327
- Napi::TypeError::New(env, kErrorExpectedArgumentToBeNumber).ThrowAsJavaScriptException();
328
- return env.Null();
329
- }
330
-
331
- if (info.Length() < 2 || !info[1].IsNumber()) {
332
- Napi::TypeError::New(env, kErrorExpectedArgumentToBeNumber).ThrowAsJavaScriptException();
333
- return env.Null();
334
- }
335
-
336
- uint16_t label = (uint16_t)info[0].As<Napi::Number>().Uint32Value();
337
- uint8_t desiredLength = (uint8_t)info[1].As<Napi::Number>().Uint32Value();
338
-
339
- userContext->GetCredentialManager()->SetupAsyncFunctions();
340
- userContext->GetCryptoManager()->SetupAsyncFunctions();
341
-
342
- EdhocKeyExporterAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
343
- userContext->GetCredentialManager()->CleanupAsyncFunctions();
344
- userContext->GetCryptoManager()->CleanupAsyncFunctions();
345
- if (!userContext->error.IsEmpty()) {
346
- userContext->error.ThrowAsJavaScriptException();
347
- }
348
- };
349
-
350
- EdhocKeyExporterAsyncWorker* worker = new EdhocKeyExporterAsyncWorker(env, context, label, desiredLength, callback);
351
- worker->Queue();
352
-
353
- return worker->GetPromise();
354
- }
355
-
356
- Napi::Value LibEDHOC::KeyUpdate(const Napi::CallbackInfo& info) {
357
- Napi::Env env = info.Env();
358
- Napi::HandleScope scope(env);
359
-
360
- if (info.Length() < 1 || !info[0].IsBuffer()) {
361
- Napi::TypeError::New(env, kErrorExpectedFirstArgumentToBeBuffer).ThrowAsJavaScriptException();
362
- return env.Null();
363
- }
364
-
365
- Napi::Buffer<uint8_t> contextBuffer = info[0].As<Napi::Buffer<uint8_t>>();
366
- std::vector<uint8_t> contextBufferVector(contextBuffer.Data(), contextBuffer.Data() + contextBuffer.Length());
367
-
368
- userContext->GetCredentialManager()->SetupAsyncFunctions();
369
- userContext->GetCryptoManager()->SetupAsyncFunctions();
370
-
371
- EdhocKeyUpdateAsyncWorker::CallbackType callback = [this](Napi::Env& env) {
372
- userContext->GetCredentialManager()->CleanupAsyncFunctions();
373
- userContext->GetCryptoManager()->CleanupAsyncFunctions();
374
- if (!userContext->error.IsEmpty()) {
375
- userContext->error.ThrowAsJavaScriptException();
376
- }
377
- };
378
-
379
- EdhocKeyUpdateAsyncWorker* worker = new EdhocKeyUpdateAsyncWorker(env, context, contextBufferVector, callback);
380
- worker->Queue();
381
-
382
- return worker->GetPromise();
383
- }
384
-
385
- Napi::Object LibEDHOC::Init(Napi::Env env, Napi::Object exports) {
386
- Napi::HandleScope scope(env);
387
- Napi::Function func =
388
- DefineClass(env, kClassNameLibEDHOC,
389
- {
390
- InstanceAccessor(kJsPropertyConnectionID, &LibEDHOC::GetCID, &LibEDHOC::SetCID),
391
- InstanceAccessor<&LibEDHOC::GetPeerCID>(kJsPropertyPeerConnectionID),
392
- InstanceAccessor(kJsPropertyMethods, &LibEDHOC::GetMethods, &LibEDHOC::SetMethods),
393
- InstanceAccessor<&LibEDHOC::GetSelectedMethod>(kJsPropertySelectedMethod),
394
- InstanceAccessor(kJsPropertyCipherSuites, &LibEDHOC::GetCipherSuites, &LibEDHOC::SetCipherSuites),
395
- InstanceAccessor<&LibEDHOC::GetSelectedCipherSuite>(kJsPropertySelectedCipherSuite),
396
- InstanceAccessor(kJsPropertyLogger, &LibEDHOC::GetLogger, &LibEDHOC::SetLogger),
397
- InstanceMethod(kMethodComposeMessage1, &LibEDHOC::ComposeMessage1),
398
- InstanceMethod(kMethodProcessMessage1, &LibEDHOC::ProcessMessage1),
399
- InstanceMethod(kMethodComposeMessage2, &LibEDHOC::ComposeMessage2),
400
- InstanceMethod(kMethodProcessMessage2, &LibEDHOC::ProcessMessage2),
401
- InstanceMethod(kMethodComposeMessage3, &LibEDHOC::ComposeMessage3),
402
- InstanceMethod(kMethodProcessMessage3, &LibEDHOC::ProcessMessage3),
403
- InstanceMethod(kMethodComposeMessage4, &LibEDHOC::ComposeMessage4),
404
- InstanceMethod(kMethodProcessMessage4, &LibEDHOC::ProcessMessage4),
405
- InstanceMethod(kMethodExportOSCORE, &LibEDHOC::ExportOSCORE),
406
- InstanceMethod(kMethodExportKey, &LibEDHOC::ExportKey),
407
- InstanceMethod(kMethodKeyUpdate, &LibEDHOC::KeyUpdate),
408
- });
409
-
410
- Napi::FunctionReference* constructor = new Napi::FunctionReference();
411
- *constructor = Napi::Persistent(func);
412
- env.SetInstanceData(constructor);
413
-
414
- exports.Set(kClassNameLibEDHOC, func);
415
- return exports;
416
- }
417
-
418
- NODE_API_NAMED_ADDON(addon, LibEDHOC);