asherah 1.2.9 → 1.3.2
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/.asherah-version +1 -1
- package/binding.gyp +12 -2
- package/dist/asherah.d.ts +2 -1
- package/dist/asherah.js +15 -34
- package/package.json +2 -3
- package/src/napiasherah.cc +829 -47
package/.asherah-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ASHERAH_VERSION=v0.4.
|
|
1
|
+
ASHERAH_VERSION=v0.4.26
|
package/binding.gyp
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
'targets': [
|
|
3
|
-
|
|
3
|
+
{
|
|
4
4
|
'target_name': 'napiasherah',
|
|
5
5
|
'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")"],
|
|
6
|
+
"cflags": ["-fexceptions", "-g"],
|
|
7
|
+
"cflags_cc": ["-fexceptions", "-g"],
|
|
8
|
+
"cflags!": [ "-fno-exceptions"],
|
|
9
|
+
"cflags_cc!": [ "-fno-exceptions" ],
|
|
10
|
+
'xcode_settings': {
|
|
11
|
+
'OTHER_CFLAGS': [
|
|
12
|
+
'-fexceptions',
|
|
13
|
+
'-g'
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
'defines': [ 'NAPI_CPP_EXCEPTIONS', 'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS' ],
|
|
6
17
|
'sources': [
|
|
7
18
|
'lib/libasherah.h',
|
|
8
19
|
'src/napiasherah.cc'
|
|
9
20
|
],
|
|
10
|
-
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
|
|
11
21
|
'libraries': [ '../lib/libasherah.a' ]
|
|
12
22
|
}
|
|
13
23
|
]
|
package/dist/asherah.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="ref-napi" />
|
|
3
2
|
export type AsherahConfig = {
|
|
4
3
|
/** The name of this service (Required) */
|
|
5
4
|
ServiceName: string;
|
|
@@ -46,3 +45,5 @@ export declare function decrypt(partitionId: string, dataRowRecord: string): Buf
|
|
|
46
45
|
export declare function encrypt(partitionId: string, data: Buffer): string;
|
|
47
46
|
export declare function decrypt_string(partitionId: string, dataRowRecord: string): string;
|
|
48
47
|
export declare function encrypt_string(partitionId: string, data: string): string;
|
|
48
|
+
export declare function set_max_stack_alloc_item_size(max_item_size: number): void;
|
|
49
|
+
export declare function set_safety_padding_overhead(safety_padding_overhead: number): void;
|
package/dist/asherah.js
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.encrypt_string = exports.decrypt_string = exports.encrypt = exports.decrypt = exports.shutdown = exports.setup = void 0;
|
|
4
|
-
const cobhan_1 = require("cobhan");
|
|
3
|
+
exports.set_safety_padding_overhead = exports.set_max_stack_alloc_item_size = exports.encrypt_string = exports.decrypt_string = exports.encrypt = exports.decrypt = exports.shutdown = exports.setup = void 0;
|
|
5
4
|
const napi_asherah = require('../build/Release/napiasherah.node');
|
|
6
|
-
const EstimatedEncryptionOverhead = 48;
|
|
7
|
-
const EstimatedEnvelopeOverhead = 185;
|
|
8
|
-
const Base64Overhead = 1.34;
|
|
9
|
-
let EstimatedIntermediateKeyOverhead = 0;
|
|
10
|
-
function estimate_buffer(dataLen, partitionLen) {
|
|
11
|
-
const estimatedDataLen = (dataLen + EstimatedEncryptionOverhead) * Base64Overhead;
|
|
12
|
-
return EstimatedEnvelopeOverhead + EstimatedIntermediateKeyOverhead + partitionLen + estimatedDataLen;
|
|
13
|
-
}
|
|
14
5
|
function setup(config) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const result = napi_asherah.Napi_SetupJson(configJsonBuffer);
|
|
18
|
-
if (result < 0) {
|
|
19
|
-
throw new Error('setupJson failed: ' + result);
|
|
20
|
-
}
|
|
6
|
+
const configStr = JSON.stringify(config);
|
|
7
|
+
napi_asherah.Napi_SetupJson(configStr, config.ProductID.length, config.ServiceName.length, config.Verbose);
|
|
21
8
|
}
|
|
22
9
|
exports.setup = setup;
|
|
23
10
|
function shutdown() {
|
|
@@ -25,32 +12,26 @@ function shutdown() {
|
|
|
25
12
|
}
|
|
26
13
|
exports.shutdown = shutdown;
|
|
27
14
|
function decrypt(partitionId, dataRowRecord) {
|
|
28
|
-
|
|
29
|
-
const jsonBuffer = (0, cobhan_1.string_to_cbuffer)(dataRowRecord);
|
|
30
|
-
const outputDataBuffer = (0, cobhan_1.allocate_cbuffer)(jsonBuffer.byteLength);
|
|
31
|
-
const result = napi_asherah.Napi_DecryptFromJson(partitionIdBuffer, jsonBuffer, outputDataBuffer);
|
|
32
|
-
if (result < 0) {
|
|
33
|
-
throw new Error('decrypt failed: ' + result);
|
|
34
|
-
}
|
|
35
|
-
return (0, cobhan_1.cbuffer_to_buffer)(outputDataBuffer);
|
|
15
|
+
return napi_asherah.Napi_DecryptFromJsonToBuffer(partitionId, dataRowRecord);
|
|
36
16
|
}
|
|
37
17
|
exports.decrypt = decrypt;
|
|
38
18
|
function encrypt(partitionId, data) {
|
|
39
|
-
|
|
40
|
-
const dataBuffer = (0, cobhan_1.buffer_to_cbuffer)(data);
|
|
41
|
-
const outputJsonBuffer = (0, cobhan_1.allocate_cbuffer)(estimate_buffer(data.byteLength, partitionId.length));
|
|
42
|
-
const result = napi_asherah.Napi_EncryptToJson(partitionIdBuffer, dataBuffer, outputJsonBuffer);
|
|
43
|
-
if (result < 0) {
|
|
44
|
-
throw new Error('encrypt failed: ' + result);
|
|
45
|
-
}
|
|
46
|
-
return (0, cobhan_1.cbuffer_to_string)(outputJsonBuffer);
|
|
19
|
+
return napi_asherah.Napi_EncryptFromBufferToJson(partitionId, data);
|
|
47
20
|
}
|
|
48
21
|
exports.encrypt = encrypt;
|
|
49
22
|
function decrypt_string(partitionId, dataRowRecord) {
|
|
50
|
-
return
|
|
23
|
+
return napi_asherah.Napi_DecryptFromJsonToString(partitionId, dataRowRecord);
|
|
51
24
|
}
|
|
52
25
|
exports.decrypt_string = decrypt_string;
|
|
53
26
|
function encrypt_string(partitionId, data) {
|
|
54
|
-
return
|
|
27
|
+
return napi_asherah.Napi_EncryptFromStringToJson(partitionId, data);
|
|
55
28
|
}
|
|
56
29
|
exports.encrypt_string = encrypt_string;
|
|
30
|
+
function set_max_stack_alloc_item_size(max_item_size) {
|
|
31
|
+
return napi_asherah.Napi_SetMaxStackAllocItemSize(max_item_size);
|
|
32
|
+
}
|
|
33
|
+
exports.set_max_stack_alloc_item_size = set_max_stack_alloc_item_size;
|
|
34
|
+
function set_safety_padding_overhead(safety_padding_overhead) {
|
|
35
|
+
return napi_asherah.Napi_SetSafetyPaddingOverhead(safety_padding_overhead);
|
|
36
|
+
}
|
|
37
|
+
exports.set_safety_padding_overhead = set_safety_padding_overhead;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Asherah envelope encryption and key rotation library",
|
|
5
5
|
"main": "dist/asherah.js",
|
|
6
6
|
"repository": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "npx tsc",
|
|
12
12
|
"preinstall": "scripts/download-libraries.sh",
|
|
13
|
-
"install": "node-gyp rebuild",
|
|
13
|
+
"install": "CFLAGS=-fexceptions CXXFLAGS=-fexceptions node-gyp rebuild",
|
|
14
14
|
"test:mocha": "mocha",
|
|
15
15
|
"test": "nyc npm run test:mocha",
|
|
16
16
|
"posttest": "npm run lint",
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
"@types/chai": "^4.3.0",
|
|
35
35
|
"@types/mocha": "^9.1.0",
|
|
36
36
|
"@types/node": "^17.0.22",
|
|
37
|
-
"@types/ref-napi": "^3.0.4",
|
|
38
37
|
"@typescript-eslint/eslint-plugin": "^5.16.0",
|
|
39
38
|
"@typescript-eslint/parser": "^5.16.0",
|
|
40
39
|
"benchmark": "^2.1.4",
|
package/src/napiasherah.cc
CHANGED
|
@@ -1,86 +1,868 @@
|
|
|
1
|
-
#include <napi.h>
|
|
2
1
|
#include "../lib/libasherah.h"
|
|
2
|
+
#include <iostream>
|
|
3
|
+
#include <napi.h>
|
|
4
|
+
|
|
5
|
+
#define unlikely(expr) __builtin_expect(!!(expr), 0)
|
|
6
|
+
#define likely(expr) __builtin_expect(!!(expr), 1)
|
|
7
|
+
|
|
8
|
+
const size_t cobhan_header_size = 64 / 8;
|
|
9
|
+
const size_t est_encryption_overhead = 48;
|
|
10
|
+
const size_t est_envelope_overhead = 185;
|
|
11
|
+
const double base64_overhead = 1.34;
|
|
12
|
+
|
|
13
|
+
size_t est_intermediate_key_overhead = 0;
|
|
14
|
+
size_t safety_padding = 0;
|
|
15
|
+
size_t max_stack_alloc_size = 2048;
|
|
16
|
+
|
|
17
|
+
const char *setupjson_failed_message = "SetupJson failed: ";
|
|
18
|
+
const char *decrypt_failed_message = "Decrypt failed: ";
|
|
19
|
+
const char *encrypt_failed_message = "Encrypt failed: ";
|
|
20
|
+
|
|
21
|
+
int32_t setup_state = 0;
|
|
22
|
+
int32_t verbose_flag = 0;
|
|
23
|
+
|
|
24
|
+
__attribute__((always_inline)) inline void debug_log(std::string message) {
|
|
25
|
+
if (unlikely(verbose_flag)) {
|
|
26
|
+
std::cerr << "asherah-node:" << message << std::endl << std::flush;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
__attribute__((always_inline)) inline void debug_log_alloca(size_t length) {
|
|
31
|
+
if (unlikely(verbose_flag)) {
|
|
32
|
+
std::cerr << "asherah-node:" << "Calling alloca(" << length << ") (stack)" << std::endl << std::flush;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
__attribute__((always_inline)) inline void error_log(std::string message) {
|
|
37
|
+
if (unlikely(verbose_flag)) {
|
|
38
|
+
std::cerr << "asherah-node:" << message << std::endl << std::flush;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::string napi_status_to_string(napi_status status) {
|
|
43
|
+
switch (status) {
|
|
44
|
+
case napi_ok:
|
|
45
|
+
return "napi_ok";
|
|
46
|
+
case napi_invalid_arg:
|
|
47
|
+
return "napi_invalid_arg";
|
|
48
|
+
case napi_object_expected:
|
|
49
|
+
return "napi_object_expected";
|
|
50
|
+
case napi_string_expected:
|
|
51
|
+
return "napi_string_expected";
|
|
52
|
+
case napi_name_expected:
|
|
53
|
+
return "napi_name_expected";
|
|
54
|
+
case napi_function_expected:
|
|
55
|
+
return "napi_function_expected";
|
|
56
|
+
case napi_number_expected:
|
|
57
|
+
return "napi_number_expected";
|
|
58
|
+
case napi_boolean_expected:
|
|
59
|
+
return "napi_boolean_expected";
|
|
60
|
+
case napi_array_expected:
|
|
61
|
+
return "napi_array_expected";
|
|
62
|
+
case napi_generic_failure:
|
|
63
|
+
return "napi_generic_failure";
|
|
64
|
+
case napi_pending_exception:
|
|
65
|
+
return "napi_pending_exception";
|
|
66
|
+
case napi_cancelled:
|
|
67
|
+
return "napi_cancelled";
|
|
68
|
+
case napi_escape_called_twice:
|
|
69
|
+
return "napi_escape_called_twice";
|
|
70
|
+
case napi_handle_scope_mismatch:
|
|
71
|
+
return "napi_handle_scope_mismatch";
|
|
72
|
+
case napi_callback_scope_mismatch:
|
|
73
|
+
return "napi_callback_scope_mismatch";
|
|
74
|
+
case napi_queue_full:
|
|
75
|
+
return "napi_queue_full";
|
|
76
|
+
case napi_closing:
|
|
77
|
+
return "napi_closing";
|
|
78
|
+
case napi_bigint_expected:
|
|
79
|
+
return "napi_bigint_expected";
|
|
80
|
+
case napi_date_expected:
|
|
81
|
+
return "napi_date_expected";
|
|
82
|
+
case napi_arraybuffer_expected:
|
|
83
|
+
return "napi_arraybuffer_expected";
|
|
84
|
+
case napi_detachable_arraybuffer_expected:
|
|
85
|
+
return "napi_detachable_arraybuffer_expected";
|
|
86
|
+
case napi_would_deadlock:
|
|
87
|
+
return "napi_would_deadlock";
|
|
88
|
+
default:
|
|
89
|
+
return "Unknown napi_status";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
94
|
+
LogErrorAndThrow(Napi::Env &env, std::string error_msg) {
|
|
95
|
+
error_log(error_msg);
|
|
96
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
97
|
+
return env.Null();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
__attribute__((always_inline)) inline size_t
|
|
101
|
+
cobhan_buffer_size(size_t dataLen) {
|
|
102
|
+
return dataLen + cobhan_header_size + safety_padding +
|
|
103
|
+
1; // Add one for possible NULL delimiter due to Node string functions
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
__attribute__((always_inline)) inline size_t
|
|
107
|
+
estimate_asherah_output_size(size_t dataLen, size_t partitionLen) {
|
|
108
|
+
double estimatedDataLen =
|
|
109
|
+
double(dataLen + est_encryption_overhead) * base64_overhead;
|
|
110
|
+
if(unlikely(verbose_flag)) {
|
|
111
|
+
std::string log_msg = "estimate_asherah_output_size(" + std::to_string(dataLen) + ", " + std::to_string(partitionLen) + ") estimatedDataLen: " + std::to_string(estimatedDataLen) + " base64_overhead: " + std::to_string(base64_overhead) + " est_encryption_overhead: " + std::to_string(est_encryption_overhead);
|
|
112
|
+
debug_log(log_msg);
|
|
113
|
+
}
|
|
114
|
+
size_t asherah_output_size = size_t(est_envelope_overhead + est_intermediate_key_overhead +
|
|
115
|
+
partitionLen + estimatedDataLen + safety_padding);
|
|
116
|
+
if(unlikely(verbose_flag)) {
|
|
117
|
+
std::string log_msg = "estimate_asherah_output_size(" + std::to_string(dataLen) + ", " + std::to_string(partitionLen) + ") estimatedDataLen: " + std::to_string(estimatedDataLen) + " asherah_output_size: " + std::to_string(asherah_output_size);
|
|
118
|
+
debug_log(log_msg);
|
|
119
|
+
}
|
|
120
|
+
return asherah_output_size;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
__attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
|
|
124
|
+
size_t length) {
|
|
125
|
+
*((int32_t *)buffer) = length;
|
|
126
|
+
// Reserved for future use
|
|
127
|
+
*((int32_t *)(buffer + sizeof(int32_t))) = 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
__attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
131
|
+
allocate_cbuffer(size_t length) {
|
|
132
|
+
size_t cobhanBufferSize = cobhan_buffer_size(length);
|
|
133
|
+
if (unlikely(verbose_flag)) {
|
|
134
|
+
std::string log_msg =
|
|
135
|
+
"allocate_cbuffer(" + std::to_string(length) +
|
|
136
|
+
") (heap) cobhanBufferSize: " + std::to_string(cobhanBufferSize);
|
|
137
|
+
debug_log(log_msg);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
char *cobhanBuffer = new (std::nothrow) char[cobhanBufferSize];
|
|
141
|
+
if (unlikely(cobhanBuffer == nullptr)) {
|
|
142
|
+
std::string error_msg = "allocate_cbuffer: new[" +
|
|
143
|
+
std::to_string(cobhanBufferSize) + " returned null";
|
|
144
|
+
error_log(error_msg);
|
|
145
|
+
return nullptr;
|
|
146
|
+
}
|
|
147
|
+
std::unique_ptr<char[]> cobhanBufferPtr(cobhanBuffer);
|
|
148
|
+
configure_cbuffer(cobhanBuffer, length + safety_padding);
|
|
149
|
+
return cobhanBufferPtr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
153
|
+
cbuffer_to_nstring(Napi::Env &env, char *cobhanBuffer) {
|
|
154
|
+
napi_value output;
|
|
155
|
+
|
|
156
|
+
// Using C function because it allows length delimited input
|
|
157
|
+
napi_status status = napi_create_string_utf8(
|
|
158
|
+
env, ((const char *)cobhanBuffer) + cobhan_header_size,
|
|
159
|
+
*((int *)cobhanBuffer), &output);
|
|
160
|
+
|
|
161
|
+
if (unlikely(status != napi_ok)) {
|
|
162
|
+
return LogErrorAndThrow(
|
|
163
|
+
env, "cbuffer_to_nstring: napi_create_string_utf8 failed: " +
|
|
164
|
+
napi_status_to_string(status));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return Napi::String(env, output);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
__attribute__((always_inline)) inline size_t
|
|
171
|
+
nstring_utf8_length(Napi::Env &env, Napi::String &str) {
|
|
172
|
+
napi_status status;
|
|
173
|
+
size_t utf8_length;
|
|
174
|
+
|
|
175
|
+
status = napi_get_value_string_utf8(env, str, nullptr, 0, &utf8_length);
|
|
176
|
+
if (unlikely(status != napi_ok)) {
|
|
177
|
+
LogErrorAndThrow(
|
|
178
|
+
env,
|
|
179
|
+
"nstring_utf8_length: napi_get_value_string_utf8 length check failed" +
|
|
180
|
+
napi_status_to_string(status));
|
|
181
|
+
return (size_t)(-1);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return utf8_length;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
__attribute__((always_inline)) inline char *
|
|
188
|
+
copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str, size_t utf8_length,
|
|
189
|
+
char *cbuffer, size_t *length = nullptr) {
|
|
190
|
+
napi_status status;
|
|
191
|
+
size_t copied_bytes;
|
|
192
|
+
status = napi_get_value_string_utf8(env, str, cbuffer + cobhan_header_size,
|
|
193
|
+
utf8_length + 1, &copied_bytes);
|
|
194
|
+
if (unlikely(status != napi_ok)) {
|
|
195
|
+
LogErrorAndThrow(env,
|
|
196
|
+
"copy_nstring_to_cbuffer: Napi utf8 string conversion "
|
|
197
|
+
"failure: " +
|
|
198
|
+
napi_status_to_string(status));
|
|
199
|
+
return nullptr;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (unlikely(copied_bytes != utf8_length)) {
|
|
203
|
+
LogErrorAndThrow(env,
|
|
204
|
+
"copy_nstring_to_cbuffer: Did not copy expected number "
|
|
205
|
+
"of bytes " +
|
|
206
|
+
std::to_string(utf8_length) + " copied " +
|
|
207
|
+
std::to_string(copied_bytes));
|
|
208
|
+
return nullptr;
|
|
209
|
+
}
|
|
3
210
|
|
|
4
|
-
|
|
5
|
-
|
|
211
|
+
*((int *)cbuffer) = copied_bytes;
|
|
212
|
+
*((int *)(cbuffer + sizeof(int32_t))) = 0;
|
|
213
|
+
|
|
214
|
+
if (length != nullptr)
|
|
215
|
+
*length = copied_bytes;
|
|
216
|
+
return cbuffer;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
__attribute__((always_inline)) inline Napi::Buffer<unsigned char>
|
|
220
|
+
cbuffer_to_nbuffer(Napi::Env &env, char *cobhanBuffer) {
|
|
221
|
+
return Napi::Buffer<unsigned char>::Copy(
|
|
222
|
+
env, ((unsigned char *)cobhanBuffer) + cobhan_header_size,
|
|
223
|
+
*((int *)cobhanBuffer));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
Napi::Value Napi_SetupJson(const Napi::CallbackInfo &info) {
|
|
6
227
|
Napi::Env env = info.Env();
|
|
7
228
|
|
|
8
|
-
if
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
229
|
+
if(unlikely(verbose_flag)) {
|
|
230
|
+
debug_log("SetupJson called");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (unlikely(setup_state == 1)) {
|
|
234
|
+
return LogErrorAndThrow(env, setupjson_failed_message +
|
|
235
|
+
std::string("SetupJson called twice"));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (unlikely(info.Length() < 3)) {
|
|
239
|
+
return LogErrorAndThrow(env, "SetupJson: Wrong number of arguments");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (unlikely(!info[0].IsString() || !info[1].IsNumber() ||
|
|
243
|
+
!info[2].IsNumber() || !info[3].IsBoolean())) {
|
|
244
|
+
return LogErrorAndThrow(env, "SetupJson: Wrong argument types");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
Napi::Boolean verbose = info[3].As<Napi::Boolean>();
|
|
248
|
+
verbose.Value() ? verbose_flag = 1 : verbose_flag = 0;
|
|
249
|
+
debug_log("SetupJson: verbose_flag: " + std::to_string(verbose_flag) +
|
|
250
|
+
" verbose.Value(): " + std::to_string(verbose.Value()));
|
|
251
|
+
|
|
252
|
+
// Determine size
|
|
253
|
+
size_t config_utf8_length;
|
|
254
|
+
Napi::String configJson = info[0].As<Napi::String>();
|
|
255
|
+
config_utf8_length = nstring_utf8_length(env, configJson);
|
|
256
|
+
if (unlikely(config_utf8_length == (size_t)(-1))) {
|
|
257
|
+
return LogErrorAndThrow(
|
|
258
|
+
env, encrypt_failed_message +
|
|
259
|
+
std::string(" failed to get configJson utf8 length"));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Allocate
|
|
263
|
+
char *configJsonCobhanBuffer;
|
|
264
|
+
std::unique_ptr<char[]> configJsonCobhanBufferPtr;
|
|
265
|
+
if (config_utf8_length < max_stack_alloc_size) {
|
|
266
|
+
size_t cobhan_buf_size = cobhan_buffer_size(config_utf8_length);
|
|
267
|
+
debug_log_alloca(cobhan_buf_size);
|
|
268
|
+
configJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
269
|
+
} else {
|
|
270
|
+
configJsonCobhanBufferPtr = allocate_cbuffer(config_utf8_length);
|
|
271
|
+
configJsonCobhanBuffer = configJsonCobhanBufferPtr.get();
|
|
272
|
+
}
|
|
273
|
+
if (unlikely(configJsonCobhanBuffer == nullptr)) {
|
|
274
|
+
return LogErrorAndThrow(
|
|
275
|
+
env, encrypt_failed_message +
|
|
276
|
+
std::string(" failed to allocate configJson cobhan buffer"));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Copy
|
|
280
|
+
size_t config_copied_bytes;
|
|
281
|
+
configJsonCobhanBuffer =
|
|
282
|
+
copy_nstring_to_cbuffer(env, configJson, config_utf8_length,
|
|
283
|
+
configJsonCobhanBuffer, &config_copied_bytes);
|
|
284
|
+
if (unlikely(configJsonCobhanBuffer == nullptr)) {
|
|
285
|
+
return LogErrorAndThrow(
|
|
286
|
+
env, encrypt_failed_message +
|
|
287
|
+
std::string(" failed to copy configJson to cobhan buffer"));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
Napi::Number productIdLength = info[1].As<Napi::Number>();
|
|
291
|
+
Napi::Number serviceNameLength = info[2].As<Napi::Number>();
|
|
292
|
+
|
|
293
|
+
est_intermediate_key_overhead =
|
|
294
|
+
productIdLength.Int32Value() + serviceNameLength.Int32Value();
|
|
295
|
+
|
|
296
|
+
// extern GoInt32 SetupJson(void* configJson);
|
|
297
|
+
GoInt32 result = SetupJson(configJsonCobhanBuffer);
|
|
298
|
+
if (unlikely(result < 0)) {
|
|
299
|
+
return LogErrorAndThrow(env,
|
|
300
|
+
setupjson_failed_message + std::to_string(result));
|
|
301
|
+
}
|
|
302
|
+
setup_state = 1;
|
|
303
|
+
return env.Null();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
307
|
+
size_t data_bytes, char *partitionIdCobhanBuffer,
|
|
308
|
+
char *dataCobhanBuffer) {
|
|
309
|
+
|
|
310
|
+
size_t asherah_output_size =
|
|
311
|
+
estimate_asherah_output_size(data_bytes, partition_bytes);
|
|
312
|
+
|
|
313
|
+
if(unlikely(verbose_flag)) {
|
|
314
|
+
debug_log("encrypt_to_json asherah_output_size " +
|
|
315
|
+
std::to_string(asherah_output_size));
|
|
12
316
|
}
|
|
13
317
|
|
|
14
|
-
|
|
318
|
+
char *cobhanOutputBuffer;
|
|
319
|
+
std::unique_ptr<char[]> cobhanOutputBufferPtr;
|
|
320
|
+
if (asherah_output_size < max_stack_alloc_size) {
|
|
321
|
+
size_t cobhan_ouput_buffer_size = cobhan_buffer_size(asherah_output_size);
|
|
322
|
+
debug_log_alloca(cobhan_ouput_buffer_size);
|
|
323
|
+
cobhanOutputBuffer = (char *)alloca(cobhan_ouput_buffer_size);
|
|
324
|
+
configure_cbuffer(cobhanOutputBuffer, asherah_output_size + safety_padding);
|
|
325
|
+
} else {
|
|
326
|
+
cobhanOutputBufferPtr = allocate_cbuffer(asherah_output_size);
|
|
327
|
+
cobhanOutputBuffer = cobhanOutputBufferPtr.get();
|
|
328
|
+
}
|
|
329
|
+
if (unlikely(cobhanOutputBuffer == nullptr)) {
|
|
330
|
+
return LogErrorAndThrow(
|
|
331
|
+
env, encrypt_failed_message +
|
|
332
|
+
std::string(" failed to allocate cobhan output buffer"));
|
|
333
|
+
}
|
|
15
334
|
|
|
16
|
-
GoInt32
|
|
335
|
+
// extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void*
|
|
336
|
+
// jsonPtr);
|
|
337
|
+
GoInt32 result = EncryptToJson(partitionIdCobhanBuffer, dataCobhanBuffer,
|
|
338
|
+
cobhanOutputBuffer);
|
|
339
|
+
if (unlikely(result < 0)) {
|
|
340
|
+
return LogErrorAndThrow(env,
|
|
341
|
+
encrypt_failed_message + std::to_string(result));
|
|
342
|
+
}
|
|
17
343
|
|
|
18
|
-
Napi::
|
|
19
|
-
return
|
|
344
|
+
Napi::Value output = cbuffer_to_nstring(env, cobhanOutputBuffer);
|
|
345
|
+
return output;
|
|
20
346
|
}
|
|
21
347
|
|
|
22
|
-
|
|
23
|
-
Napi::Value Napi_EncryptToJson(const Napi::CallbackInfo& info) {
|
|
348
|
+
Napi::Value Napi_EncryptFromBufferToJson(const Napi::CallbackInfo &info) {
|
|
24
349
|
Napi::Env env = info.Env();
|
|
25
350
|
|
|
26
|
-
if
|
|
27
|
-
|
|
28
|
-
.ThrowAsJavaScriptException();
|
|
29
|
-
return env.Null();
|
|
351
|
+
if(unlikely(verbose_flag)) {
|
|
352
|
+
debug_log("EncryptFromBufferToJson called");
|
|
30
353
|
}
|
|
31
354
|
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
355
|
+
if (unlikely(setup_state == 0)) {
|
|
356
|
+
return LogErrorAndThrow(env, encrypt_failed_message +
|
|
357
|
+
std::string("SetupJson not called"));
|
|
35
358
|
}
|
|
36
359
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
360
|
+
if (unlikely(info.Length() < 2)) {
|
|
361
|
+
return LogErrorAndThrow(
|
|
362
|
+
env, "EncryptFromBufferToJson: Wrong number of arguments");
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
|
|
366
|
+
return LogErrorAndThrow(env,
|
|
367
|
+
"EncryptFromBufferToJson: Wrong argument types");
|
|
368
|
+
}
|
|
40
369
|
|
|
41
|
-
|
|
370
|
+
// Determine size
|
|
371
|
+
size_t partition_utf8_length;
|
|
372
|
+
Napi::String partitionId = info[0].As<Napi::String>();
|
|
373
|
+
partition_utf8_length = nstring_utf8_length(env, partitionId);
|
|
374
|
+
if (unlikely(partition_utf8_length == (size_t)(-1))) {
|
|
375
|
+
return LogErrorAndThrow(
|
|
376
|
+
env, encrypt_failed_message +
|
|
377
|
+
std::string(" failed to get partitionId utf8 length"));
|
|
378
|
+
}
|
|
42
379
|
|
|
43
|
-
|
|
44
|
-
|
|
380
|
+
// Allocate
|
|
381
|
+
char *partitionIdCobhanBuffer;
|
|
382
|
+
std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
|
|
383
|
+
if (partition_utf8_length < max_stack_alloc_size) {
|
|
384
|
+
size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
|
|
385
|
+
debug_log_alloca(cobhan_buf_size);
|
|
386
|
+
partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
387
|
+
} else {
|
|
388
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
389
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
390
|
+
}
|
|
391
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
392
|
+
return LogErrorAndThrow(
|
|
393
|
+
env, encrypt_failed_message +
|
|
394
|
+
std::string(" failed to allocate partitionId cobhan buffer"));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Copy
|
|
398
|
+
size_t partition_copied_bytes;
|
|
399
|
+
partitionIdCobhanBuffer =
|
|
400
|
+
copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
|
|
401
|
+
partitionIdCobhanBuffer, &partition_copied_bytes);
|
|
402
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
403
|
+
return LogErrorAndThrow(
|
|
404
|
+
env, encrypt_failed_message +
|
|
405
|
+
std::string(" failed to copy partitionId to cobhan buffer"));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Determine size
|
|
409
|
+
Napi::Buffer<unsigned char> inputNapiBuffer =
|
|
410
|
+
info[1].As<Napi::Buffer<unsigned char>>();
|
|
411
|
+
size_t input_byte_length = inputNapiBuffer.ByteLength();
|
|
412
|
+
|
|
413
|
+
// Allocate
|
|
414
|
+
char *inputBuffer;
|
|
415
|
+
std::unique_ptr<char[]> inputBufferPtr;
|
|
416
|
+
if (input_byte_length < max_stack_alloc_size) {
|
|
417
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_byte_length);
|
|
418
|
+
debug_log_alloca(cobhan_buf_size);
|
|
419
|
+
inputBuffer = (char *)alloca(cobhan_buf_size);
|
|
420
|
+
} else {
|
|
421
|
+
inputBufferPtr = allocate_cbuffer(input_byte_length);
|
|
422
|
+
inputBuffer = inputBufferPtr.get();
|
|
423
|
+
}
|
|
424
|
+
if (unlikely(inputBuffer == nullptr)) {
|
|
425
|
+
return LogErrorAndThrow(
|
|
426
|
+
env,
|
|
427
|
+
encrypt_failed_message +
|
|
428
|
+
std::string(" failed to allocate cobhan buffer for input buffer"));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Copy
|
|
432
|
+
memcpy(inputBuffer + cobhan_header_size, inputNapiBuffer.Data(),
|
|
433
|
+
input_byte_length);
|
|
434
|
+
configure_cbuffer(inputBuffer, input_byte_length);
|
|
435
|
+
|
|
436
|
+
return encrypt_to_json(env, partition_copied_bytes, input_byte_length,
|
|
437
|
+
partitionIdCobhanBuffer, inputBuffer);
|
|
45
438
|
}
|
|
46
439
|
|
|
47
|
-
|
|
48
|
-
Napi::Value Napi_DecryptFromJson(const Napi::CallbackInfo& info) {
|
|
440
|
+
Napi::Value Napi_EncryptFromStringToJson(const Napi::CallbackInfo &info) {
|
|
49
441
|
Napi::Env env = info.Env();
|
|
50
442
|
|
|
51
|
-
if
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
443
|
+
if(unlikely(verbose_flag)) {
|
|
444
|
+
debug_log("EncryptFromStringToJson called");
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (unlikely(setup_state == 0)) {
|
|
448
|
+
return LogErrorAndThrow(env, encrypt_failed_message +
|
|
449
|
+
std::string("SetupJson not called"));
|
|
55
450
|
}
|
|
56
451
|
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
452
|
+
if (unlikely(info.Length() < 2)) {
|
|
453
|
+
return LogErrorAndThrow(
|
|
454
|
+
env, "EncryptFromStringToJson: Wrong number of arguments");
|
|
60
455
|
}
|
|
61
456
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
457
|
+
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
458
|
+
return LogErrorAndThrow(env,
|
|
459
|
+
"EncryptFromStringToJson: Wrong argument types");
|
|
460
|
+
}
|
|
65
461
|
|
|
66
|
-
|
|
462
|
+
// Determine size
|
|
463
|
+
size_t partition_utf8_length;
|
|
464
|
+
Napi::String partitionId = info[0].As<Napi::String>();
|
|
465
|
+
partition_utf8_length = nstring_utf8_length(env, partitionId);
|
|
466
|
+
if (unlikely(partition_utf8_length == (size_t)(-1))) {
|
|
467
|
+
return LogErrorAndThrow(
|
|
468
|
+
env, encrypt_failed_message +
|
|
469
|
+
std::string(" failed to get partitionId utf8 length"));
|
|
470
|
+
}
|
|
67
471
|
|
|
68
|
-
|
|
69
|
-
|
|
472
|
+
// Allocate
|
|
473
|
+
char *partitionIdCobhanBuffer;
|
|
474
|
+
std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
|
|
475
|
+
if (partition_utf8_length < max_stack_alloc_size) {
|
|
476
|
+
size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
|
|
477
|
+
debug_log_alloca(cobhan_buf_size);
|
|
478
|
+
partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
479
|
+
} else {
|
|
480
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
481
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
482
|
+
}
|
|
483
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
484
|
+
return LogErrorAndThrow(
|
|
485
|
+
env, encrypt_failed_message +
|
|
486
|
+
std::string(" failed to allocate partitionId cobhan buffer"));
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Copy
|
|
490
|
+
size_t partition_copied_bytes;
|
|
491
|
+
partitionIdCobhanBuffer =
|
|
492
|
+
copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
|
|
493
|
+
partitionIdCobhanBuffer, &partition_copied_bytes);
|
|
494
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
495
|
+
return LogErrorAndThrow(
|
|
496
|
+
env, encrypt_failed_message +
|
|
497
|
+
std::string(" failed to copy partitionId to cobhan buffer"));
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Determine size
|
|
501
|
+
size_t input_utf8_length;
|
|
502
|
+
Napi::String input = info[1].As<Napi::String>();
|
|
503
|
+
input_utf8_length = nstring_utf8_length(env, input);
|
|
504
|
+
if (unlikely(input_utf8_length == (size_t)(-1))) {
|
|
505
|
+
return LogErrorAndThrow(
|
|
506
|
+
env, encrypt_failed_message +
|
|
507
|
+
std::string(" failed to get input utf8 length"));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Allocate
|
|
511
|
+
char *inputCobhanBuffer;
|
|
512
|
+
std::unique_ptr<char[]> inputCobhanBufferPtr;
|
|
513
|
+
if (input_utf8_length < max_stack_alloc_size) {
|
|
514
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
|
|
515
|
+
debug_log_alloca(cobhan_buf_size);
|
|
516
|
+
inputCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
517
|
+
} else {
|
|
518
|
+
inputCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
|
|
519
|
+
inputCobhanBuffer = inputCobhanBufferPtr.get();
|
|
520
|
+
}
|
|
521
|
+
if (unlikely(inputCobhanBuffer == nullptr)) {
|
|
522
|
+
return LogErrorAndThrow(
|
|
523
|
+
env, encrypt_failed_message +
|
|
524
|
+
std::string(" failed to allocate input cobhan buffer"));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Copy
|
|
528
|
+
size_t input_copied_bytes;
|
|
529
|
+
inputCobhanBuffer = copy_nstring_to_cbuffer(
|
|
530
|
+
env, input, input_utf8_length, inputCobhanBuffer, &input_copied_bytes);
|
|
531
|
+
if (unlikely(inputCobhanBuffer == nullptr)) {
|
|
532
|
+
return LogErrorAndThrow(
|
|
533
|
+
env, encrypt_failed_message +
|
|
534
|
+
std::string(" failed to copy input to cobhan buffer"));
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return encrypt_to_json(env, partition_copied_bytes, input_utf8_length,
|
|
538
|
+
partitionIdCobhanBuffer, inputCobhanBuffer);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
Napi::Value Napi_DecryptFromJsonToBuffer(const Napi::CallbackInfo &info) {
|
|
542
|
+
Napi::Env env = info.Env();
|
|
543
|
+
|
|
544
|
+
if(unlikely(verbose_flag)) {
|
|
545
|
+
debug_log("DecryptFromJsonToBuffer called");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (unlikely(setup_state == 0)) {
|
|
549
|
+
return LogErrorAndThrow(env, decrypt_failed_message +
|
|
550
|
+
std::string("SetupJson not called"));
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (unlikely(info.Length() < 2)) {
|
|
554
|
+
return LogErrorAndThrow(
|
|
555
|
+
env, "DecryptFromJsonToBuffer: Wrong number of arguments");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
559
|
+
return LogErrorAndThrow(env,
|
|
560
|
+
"DecryptFromJsonToBuffer: Wrong argument types");
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Determine size
|
|
564
|
+
size_t partition_utf8_length, partition_copied_bytes;
|
|
565
|
+
Napi::String partitionId = info[0].As<Napi::String>();
|
|
566
|
+
partition_utf8_length = nstring_utf8_length(env, partitionId);
|
|
567
|
+
if (unlikely(partition_utf8_length == (size_t)(-1))) {
|
|
568
|
+
return LogErrorAndThrow(
|
|
569
|
+
env, decrypt_failed_message +
|
|
570
|
+
std::string(" failed to get partitionId utf8 length"));
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Allocate
|
|
574
|
+
char *partitionIdCobhanBuffer;
|
|
575
|
+
std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
|
|
576
|
+
if (partition_utf8_length < max_stack_alloc_size) {
|
|
577
|
+
size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
|
|
578
|
+
debug_log_alloca(cobhan_buf_size);
|
|
579
|
+
partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
580
|
+
} else {
|
|
581
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
582
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
583
|
+
}
|
|
584
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
585
|
+
return LogErrorAndThrow(
|
|
586
|
+
env, decrypt_failed_message +
|
|
587
|
+
std::string(" failed to allocate partitionId cobhan buffer"));
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Copy
|
|
591
|
+
partitionIdCobhanBuffer =
|
|
592
|
+
copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
|
|
593
|
+
partitionIdCobhanBuffer, &partition_copied_bytes);
|
|
594
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
595
|
+
return LogErrorAndThrow(
|
|
596
|
+
env, decrypt_failed_message +
|
|
597
|
+
std::string(" failed to copy partitionId to cobhan buffer"));
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Determine size
|
|
601
|
+
size_t input_utf8_length;
|
|
602
|
+
Napi::String input = info[1].As<Napi::String>();
|
|
603
|
+
input_utf8_length = nstring_utf8_length(env, input);
|
|
604
|
+
if (unlikely(input_utf8_length == (size_t)(-1))) {
|
|
605
|
+
return LogErrorAndThrow(
|
|
606
|
+
env, decrypt_failed_message +
|
|
607
|
+
std::string(" failed to get input utf8 length"));
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if(unlikely(verbose_flag)) {
|
|
611
|
+
debug_log("DecryptFromJsonToBuffer input size " +
|
|
612
|
+
std::to_string(input_utf8_length));
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Allocate
|
|
616
|
+
char *inputJsonCobhanBuffer;
|
|
617
|
+
std::unique_ptr<char[]> inputJsonCobhanBufferPtr;
|
|
618
|
+
if (input_utf8_length < max_stack_alloc_size) {
|
|
619
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
|
|
620
|
+
debug_log_alloca(cobhan_buf_size);
|
|
621
|
+
inputJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
622
|
+
} else {
|
|
623
|
+
inputJsonCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
|
|
624
|
+
inputJsonCobhanBuffer = inputJsonCobhanBufferPtr.get();
|
|
625
|
+
}
|
|
626
|
+
if (unlikely(inputJsonCobhanBuffer == nullptr)) {
|
|
627
|
+
return LogErrorAndThrow(
|
|
628
|
+
env, decrypt_failed_message +
|
|
629
|
+
std::string(" failed to allocate input cobhan buffer"));
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// Copy
|
|
633
|
+
size_t input_copied_bytes;
|
|
634
|
+
inputJsonCobhanBuffer =
|
|
635
|
+
copy_nstring_to_cbuffer(env, input, input_utf8_length,
|
|
636
|
+
inputJsonCobhanBuffer, &input_copied_bytes);
|
|
637
|
+
if (unlikely(inputJsonCobhanBuffer == nullptr)) {
|
|
638
|
+
return LogErrorAndThrow(
|
|
639
|
+
env, decrypt_failed_message +
|
|
640
|
+
std::string(" failed to copy inputJson to cobhan buffer"));
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
char *cobhanOutputBuffer;
|
|
644
|
+
std::unique_ptr<char[]> cobhanOutputBufferPtr;
|
|
645
|
+
if (input_utf8_length < max_stack_alloc_size) {
|
|
646
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
|
|
647
|
+
debug_log_alloca(cobhan_buf_size);
|
|
648
|
+
cobhanOutputBuffer = (char *)alloca(cobhan_buf_size);
|
|
649
|
+
configure_cbuffer(cobhanOutputBuffer, input_utf8_length);
|
|
650
|
+
} else {
|
|
651
|
+
cobhanOutputBufferPtr = allocate_cbuffer(input_utf8_length);
|
|
652
|
+
cobhanOutputBuffer = cobhanOutputBufferPtr.get();
|
|
653
|
+
}
|
|
654
|
+
if (unlikely(cobhanOutputBuffer == nullptr)) {
|
|
655
|
+
return LogErrorAndThrow(
|
|
656
|
+
env, decrypt_failed_message +
|
|
657
|
+
std::string(" failed to allocate cobhan output buffer"));
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
|
|
661
|
+
// dataPtr);
|
|
662
|
+
GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer,
|
|
663
|
+
inputJsonCobhanBuffer, cobhanOutputBuffer);
|
|
664
|
+
if (unlikely(result < 0)) {
|
|
665
|
+
return LogErrorAndThrow(env,
|
|
666
|
+
decrypt_failed_message + std::to_string(result));
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
return cbuffer_to_nbuffer(env, cobhanOutputBuffer);
|
|
70
670
|
}
|
|
71
671
|
|
|
72
|
-
|
|
73
|
-
Napi::Value Napi_Shutdown(const Napi::CallbackInfo& info) {
|
|
672
|
+
Napi::Value Napi_DecryptFromJsonToString(const Napi::CallbackInfo &info) {
|
|
74
673
|
Napi::Env env = info.Env();
|
|
674
|
+
|
|
675
|
+
if(unlikely(verbose_flag)) {
|
|
676
|
+
debug_log("DecryptFromJsonToString called");
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (unlikely(setup_state == 0)) {
|
|
680
|
+
return LogErrorAndThrow(env, decrypt_failed_message +
|
|
681
|
+
std::string("SetupJson not called"));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if (unlikely(info.Length() < 2)) {
|
|
685
|
+
return LogErrorAndThrow(
|
|
686
|
+
env, "DecryptFromJsonToString: Wrong number of arguments");
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
690
|
+
return LogErrorAndThrow(env,
|
|
691
|
+
"DecryptFromJsonToString: Wrong argument types");
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Determine size
|
|
695
|
+
size_t partition_utf8_length;
|
|
696
|
+
Napi::String partitionId = info[0].As<Napi::String>();
|
|
697
|
+
partition_utf8_length = nstring_utf8_length(env, partitionId);
|
|
698
|
+
if (unlikely(partition_utf8_length == (size_t)(-1))) {
|
|
699
|
+
return LogErrorAndThrow(
|
|
700
|
+
env, decrypt_failed_message +
|
|
701
|
+
std::string(" failed to get partitionId utf8 length"));
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Allocate
|
|
705
|
+
char *partitionIdCobhanBuffer;
|
|
706
|
+
std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
|
|
707
|
+
if (partition_utf8_length < max_stack_alloc_size) {
|
|
708
|
+
size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
|
|
709
|
+
debug_log_alloca(cobhan_buf_size);
|
|
710
|
+
partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
711
|
+
} else {
|
|
712
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
713
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
714
|
+
}
|
|
715
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
716
|
+
return LogErrorAndThrow(
|
|
717
|
+
env, decrypt_failed_message +
|
|
718
|
+
std::string(" failed to allocate partitionId cobhan buffer"));
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// Copy
|
|
722
|
+
size_t partition_copied_bytes;
|
|
723
|
+
partitionIdCobhanBuffer =
|
|
724
|
+
copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
|
|
725
|
+
partitionIdCobhanBuffer, &partition_copied_bytes);
|
|
726
|
+
if (unlikely(partitionIdCobhanBuffer == nullptr)) {
|
|
727
|
+
return LogErrorAndThrow(
|
|
728
|
+
env, decrypt_failed_message +
|
|
729
|
+
std::string(" failed to copy partitionId to cobhan buffer"));
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// Determine size
|
|
733
|
+
size_t input_utf8_length;
|
|
734
|
+
Napi::String input = info[1].As<Napi::String>();
|
|
735
|
+
input_utf8_length = nstring_utf8_length(env, input);
|
|
736
|
+
if (unlikely(input_utf8_length == (size_t)(-1))) {
|
|
737
|
+
return LogErrorAndThrow(
|
|
738
|
+
env, decrypt_failed_message +
|
|
739
|
+
std::string(" failed to get input utf8 length"));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Allocate
|
|
743
|
+
char *inputJsonCobhanBuffer;
|
|
744
|
+
std::unique_ptr<char[]> inputJsonCobhanBufferPtr;
|
|
745
|
+
if (input_utf8_length < max_stack_alloc_size) {
|
|
746
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
|
|
747
|
+
debug_log_alloca(cobhan_buf_size);
|
|
748
|
+
inputJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
|
|
749
|
+
} else {
|
|
750
|
+
inputJsonCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
|
|
751
|
+
inputJsonCobhanBuffer = inputJsonCobhanBufferPtr.get();
|
|
752
|
+
}
|
|
753
|
+
if (unlikely(inputJsonCobhanBuffer == nullptr)) {
|
|
754
|
+
return LogErrorAndThrow(
|
|
755
|
+
env, decrypt_failed_message +
|
|
756
|
+
std::string(" failed to allocate input cobhan buffer"));
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Copy
|
|
760
|
+
size_t input_copied_bytes;
|
|
761
|
+
inputJsonCobhanBuffer =
|
|
762
|
+
copy_nstring_to_cbuffer(env, input, input_utf8_length,
|
|
763
|
+
inputJsonCobhanBuffer, &input_copied_bytes);
|
|
764
|
+
if (unlikely(inputJsonCobhanBuffer == nullptr)) {
|
|
765
|
+
return LogErrorAndThrow(
|
|
766
|
+
env, decrypt_failed_message +
|
|
767
|
+
std::string(" failed to copy inputJson to cobhan buffer"));
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
char *cobhanOutputBuffer;
|
|
771
|
+
std::unique_ptr<char[]> cobhanOutputBufferPtr;
|
|
772
|
+
if (input_utf8_length < max_stack_alloc_size) {
|
|
773
|
+
size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
|
|
774
|
+
debug_log_alloca(cobhan_buf_size);
|
|
775
|
+
cobhanOutputBuffer = (char *)alloca(cobhan_buf_size);
|
|
776
|
+
configure_cbuffer(cobhanOutputBuffer, input_utf8_length);
|
|
777
|
+
} else {
|
|
778
|
+
cobhanOutputBufferPtr = allocate_cbuffer(input_utf8_length);
|
|
779
|
+
cobhanOutputBuffer = cobhanOutputBufferPtr.get();
|
|
780
|
+
}
|
|
781
|
+
if (unlikely(cobhanOutputBuffer == nullptr)) {
|
|
782
|
+
return LogErrorAndThrow(
|
|
783
|
+
env, decrypt_failed_message +
|
|
784
|
+
std::string(" failed to allocate cobhan output buffer"));
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
|
|
788
|
+
// dataPtr);
|
|
789
|
+
GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer,
|
|
790
|
+
inputJsonCobhanBuffer, cobhanOutputBuffer);
|
|
791
|
+
if (unlikely(result < 0)) {
|
|
792
|
+
return LogErrorAndThrow(env,
|
|
793
|
+
decrypt_failed_message + std::to_string(result));
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
Napi::Value output = cbuffer_to_nstring(env, cobhanOutputBuffer);
|
|
797
|
+
return output;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
Napi::Value Napi_Shutdown(const Napi::CallbackInfo &info) {
|
|
801
|
+
Napi::Env env = info.Env();
|
|
802
|
+
|
|
803
|
+
if(unlikely(verbose_flag)) {
|
|
804
|
+
debug_log("Shutdown called");
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
setup_state = 0;
|
|
808
|
+
// extern void Shutdown();
|
|
75
809
|
Shutdown();
|
|
76
810
|
return env.Null();
|
|
77
811
|
}
|
|
78
812
|
|
|
813
|
+
Napi::Value Napi_SetMaxStackAllocItemSize(const Napi::CallbackInfo &info) {
|
|
814
|
+
Napi::Env env = info.Env();
|
|
815
|
+
|
|
816
|
+
if(unlikely(verbose_flag)) {
|
|
817
|
+
debug_log("SetMaxStackAllocItemSize called");
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (unlikely(info.Length() < 1)) {
|
|
821
|
+
return LogErrorAndThrow(
|
|
822
|
+
env, "SetMaxStackAllocItemSize: Wrong number of arguments");
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
Napi::Number item_size = info[0].As<Napi::Number>();
|
|
826
|
+
|
|
827
|
+
max_stack_alloc_size = (size_t)item_size.Int32Value();
|
|
828
|
+
return env.Null();
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
Napi::Value Napi_SetSafetyPaddingOverhead(const Napi::CallbackInfo &info) {
|
|
832
|
+
Napi::Env env = info.Env();
|
|
833
|
+
|
|
834
|
+
if(unlikely(verbose_flag)) {
|
|
835
|
+
debug_log("SetSafetyPaddingOverhead called");
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (unlikely(info.Length() < 1)) {
|
|
839
|
+
return LogErrorAndThrow(
|
|
840
|
+
env, "SetSafetyPaddingOverhead: Wrong number of arguments");
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
Napi::Number safety_padding_number = info[0].As<Napi::Number>();
|
|
844
|
+
|
|
845
|
+
safety_padding = (size_t)safety_padding_number.Int32Value();
|
|
846
|
+
return env.Null();
|
|
847
|
+
}
|
|
848
|
+
|
|
79
849
|
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
80
|
-
exports.Set(Napi::String::New(env, "Napi_SetupJson"),
|
|
81
|
-
|
|
82
|
-
exports.Set(Napi::String::New(env, "
|
|
83
|
-
|
|
850
|
+
exports.Set(Napi::String::New(env, "Napi_SetupJson"),
|
|
851
|
+
Napi::Function::New(env, Napi_SetupJson));
|
|
852
|
+
exports.Set(Napi::String::New(env, "Napi_EncryptFromBufferToJson"),
|
|
853
|
+
Napi::Function::New(env, Napi_EncryptFromBufferToJson));
|
|
854
|
+
exports.Set(Napi::String::New(env, "Napi_EncryptFromStringToJson"),
|
|
855
|
+
Napi::Function::New(env, Napi_EncryptFromStringToJson));
|
|
856
|
+
exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToBuffer"),
|
|
857
|
+
Napi::Function::New(env, Napi_DecryptFromJsonToBuffer));
|
|
858
|
+
exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToString"),
|
|
859
|
+
Napi::Function::New(env, Napi_DecryptFromJsonToString));
|
|
860
|
+
exports.Set(Napi::String::New(env, "Napi_SetSafetyPaddingOverhead"),
|
|
861
|
+
Napi::Function::New(env, Napi_SetSafetyPaddingOverhead));
|
|
862
|
+
exports.Set(Napi::String::New(env, "Napi_SetMaxStackAllocItemSize"),
|
|
863
|
+
Napi::Function::New(env, Napi_SetMaxStackAllocItemSize));
|
|
864
|
+
exports.Set(Napi::String::New(env, "Napi_Shutdown"),
|
|
865
|
+
Napi::Function::New(env, Napi_Shutdown));
|
|
84
866
|
return exports;
|
|
85
867
|
}
|
|
86
868
|
|