asherah 2.0.0 → 3.0.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.
- package/binding.gyp +10 -11
- package/package.json +16 -11
- package/scripts/download-libraries.sh +261 -46
- package/src/asherah.cc +530 -442
- package/src/asherah.d.ts +7 -0
- package/src/asherah_async_worker.h +65 -0
- package/src/cobhan_buffer.h +237 -0
- package/src/cobhan_buffer_napi.h +196 -0
- package/src/logging.cc +26 -180
- package/src/logging.h +46 -43
- package/src/logging_napi.cc +151 -0
- package/src/logging_napi.h +43 -0
- package/src/napi_utils.h +160 -0
- package/src/scoped_allocate.h +53 -0
- package/src/asherah.h +0 -14
- package/src/cobhan.cc +0 -2
- package/src/cobhan.h +0 -133
- package/src/cobhan_napi_interop.h +0 -244
package/binding.gyp
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
'targets': [
|
|
3
3
|
{
|
|
4
4
|
'target_name': 'asherah',
|
|
5
|
-
'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")"],
|
|
6
|
-
"cflags": ["-fexceptions", "-g", "-O3", "-std=c++17", "-fPIC"],
|
|
7
|
-
"cflags_cc": ["-fexceptions", "-g", "-O3", "-std=c++17", "-fPIC"],
|
|
5
|
+
'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")", "lib/", "src/"],
|
|
6
|
+
"cflags": ["-fexceptions", "-g", "-O3", "-std=c++17", "-fPIC", "-Wno-unknown-pragmas"],
|
|
7
|
+
"cflags_cc": ["-fexceptions", "-g", "-O3", "-std=c++17", "-fPIC", "-Wno-unknown-pragmas"],
|
|
8
8
|
"cflags!": [ "-fno-exceptions"],
|
|
9
9
|
"cflags_cc!": [ "-fno-exceptions" ],
|
|
10
10
|
'xcode_settings': {
|
|
@@ -17,17 +17,16 @@
|
|
|
17
17
|
'-fPIC'
|
|
18
18
|
],
|
|
19
19
|
},
|
|
20
|
-
'defines': [
|
|
20
|
+
'defines': [
|
|
21
|
+
'NAPI_CPP_EXCEPTIONS',
|
|
22
|
+
'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS',
|
|
23
|
+
'NODE_ADDON_API_DISABLE_DEPRECATED',
|
|
24
|
+
'NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED'
|
|
25
|
+
],
|
|
21
26
|
'sources': [
|
|
22
|
-
'lib/libasherah.h',
|
|
23
|
-
'src/asherah.h',
|
|
24
27
|
'src/asherah.cc',
|
|
25
28
|
'src/logging.cc',
|
|
26
|
-
'src/
|
|
27
|
-
'src/cobhan_napi_interop.h',
|
|
28
|
-
'src/cobhan.h',
|
|
29
|
-
'src/cobhan.cc',
|
|
30
|
-
'src/hints.h'
|
|
29
|
+
'src/logging_napi.cc'
|
|
31
30
|
],
|
|
32
31
|
'libraries': [ '../lib/libasherah.a' ]
|
|
33
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Asherah envelope encryption and key rotation library",
|
|
5
5
|
"exports": {
|
|
6
6
|
"node-addons": "./dist/asherah.node"
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
"preinstall": "scripts/download-libraries.sh",
|
|
14
14
|
"load": "node --max-old-space-size=500 scripts/dumpster-fire.js",
|
|
15
15
|
"install": "scripts/build.sh",
|
|
16
|
+
"test:mocha-debug": "lldb -o run -- node node_modules/mocha/bin/mocha --inspect-brk",
|
|
16
17
|
"test:mocha": "mocha",
|
|
17
18
|
"test": "nyc npm run test:mocha",
|
|
19
|
+
"debug": "nyc npm run test:mocha-debug",
|
|
18
20
|
"posttest": "npm run lint",
|
|
19
21
|
"lint": "eslint src/ --ext .ts --fix"
|
|
20
22
|
},
|
|
@@ -23,14 +25,17 @@
|
|
|
23
25
|
"license": "MIT",
|
|
24
26
|
"files": [
|
|
25
27
|
"binding.gyp",
|
|
26
|
-
"src/
|
|
28
|
+
"src/asherah_async_worker.h",
|
|
27
29
|
"src/asherah.cc",
|
|
30
|
+
"src/cobhan_buffer_napi.h",
|
|
31
|
+
"src/cobhan_buffer.h",
|
|
28
32
|
"src/hints.h",
|
|
29
|
-
"src/logging.h",
|
|
30
33
|
"src/logging.cc",
|
|
31
|
-
"src/
|
|
32
|
-
"src/
|
|
33
|
-
"src/
|
|
34
|
+
"src/logging.h",
|
|
35
|
+
"src/logging_napi.cc",
|
|
36
|
+
"src/logging_napi.h",
|
|
37
|
+
"src/napi_utils.h",
|
|
38
|
+
"src/scoped_allocate.h",
|
|
34
39
|
"src/asherah.d.ts",
|
|
35
40
|
"scripts/download-libraries.sh",
|
|
36
41
|
"scripts/build.sh",
|
|
@@ -39,20 +44,21 @@
|
|
|
39
44
|
".asherah-version"
|
|
40
45
|
],
|
|
41
46
|
"devDependencies": {
|
|
42
|
-
"@
|
|
47
|
+
"@cucumber/cucumber": "^10.6.0",
|
|
43
48
|
"@types/chai": "^4.3.0",
|
|
44
|
-
"@types/mocha": "^9.1.
|
|
49
|
+
"@types/mocha": "^9.1.1",
|
|
45
50
|
"@types/node": "^17.0.22",
|
|
46
51
|
"@typescript-eslint/eslint-plugin": "^5.16.0",
|
|
47
52
|
"@typescript-eslint/parser": "^5.16.0",
|
|
48
|
-
"benchmark": "^2.1.4",
|
|
49
53
|
"chai": "^4.3.6",
|
|
50
54
|
"eslint": "^8.11.0",
|
|
51
55
|
"microtime": "^3.0.0",
|
|
52
56
|
"mocha": "^9.2.2",
|
|
57
|
+
"node-api-headers": "^1.1.0",
|
|
53
58
|
"nyc": "^15.1.0",
|
|
54
59
|
"ts-mocha": "^9.0.2",
|
|
55
|
-
"typescript": "^4.6.2"
|
|
60
|
+
"typescript": "^4.6.2",
|
|
61
|
+
"winston": "^3.11.0"
|
|
56
62
|
},
|
|
57
63
|
"mocha": {
|
|
58
64
|
"extension": [
|
|
@@ -64,7 +70,6 @@
|
|
|
64
70
|
},
|
|
65
71
|
"types": "dist/asherah.d.ts",
|
|
66
72
|
"dependencies": {
|
|
67
|
-
"cobhan": "^1.0.37",
|
|
68
73
|
"node-addon-api": "7.0.0"
|
|
69
74
|
}
|
|
70
75
|
}
|
|
@@ -1,58 +1,273 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
elif [[ ${MACHINE} == 'aarch64' ]]; then
|
|
21
|
-
echo "Linux arm64"
|
|
22
|
-
ARCHIVE=libasherah-arm64.a
|
|
23
|
-
HEADER=libasherah-arm64-archive.h
|
|
24
|
-
SUMS=SHA256SUMS
|
|
3
|
+
set -e # Exit on any command failure
|
|
4
|
+
|
|
5
|
+
# Global Constants
|
|
6
|
+
CHECK_INTERVAL_SECONDS=$((5 * 60)) # 5 minutes
|
|
7
|
+
MAX_DOWNLOAD_RETRIES=3
|
|
8
|
+
|
|
9
|
+
# Function to check if a specific file download is necessary
|
|
10
|
+
function check_download_required {
|
|
11
|
+
local file=$1
|
|
12
|
+
local no_cache=$2
|
|
13
|
+
local check_interval_seconds=$3
|
|
14
|
+
local etag_file="${file}.etag"
|
|
15
|
+
|
|
16
|
+
# If the file does not exist or the .etag file is missing, download is required
|
|
17
|
+
if [[ ! -f "$file" ]]; then
|
|
18
|
+
echo "${file} does not exist"
|
|
19
|
+
return 0 # (download required)
|
|
25
20
|
else
|
|
26
|
-
echo "
|
|
21
|
+
echo "${file} exists"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# If the file does not exist or the .etag file is missing, download is required
|
|
25
|
+
if [[ ! -f "$etag_file" ]]; then
|
|
26
|
+
echo "${etag_file} does not exist"
|
|
27
|
+
return 0 # (download required)
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# If no-cache is passed, we ignore the modified date of the .etag files
|
|
32
|
+
if [[ "$no_cache" == true ]]; then
|
|
33
|
+
return 0 # (download required)
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Check if the .etag file is older than the interval
|
|
37
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
38
|
+
# macOS uses 'stat -f'
|
|
39
|
+
last_check=$(stat -f %m "$etag_file")
|
|
40
|
+
else
|
|
41
|
+
# Linux uses 'stat -c'
|
|
42
|
+
last_check=$(stat -c %Y "$etag_file")
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
current_time=$(date +%s)
|
|
46
|
+
elapsed_time=$((current_time - last_check))
|
|
47
|
+
|
|
48
|
+
if (( elapsed_time > check_interval_seconds )); then
|
|
49
|
+
return 0 # (download required)
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
return 1 # (download not required)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Function to download a file
|
|
56
|
+
function download_file {
|
|
57
|
+
local url=$1
|
|
58
|
+
local file=$2
|
|
59
|
+
local etag_file="${file}.etag"
|
|
60
|
+
|
|
61
|
+
if ! curl -s -L --fail --etag-save "$etag_file" --etag-compare "$etag_file" -O "$url"; then
|
|
62
|
+
echo "Failed to download $url" >&2
|
|
27
63
|
exit 1
|
|
28
64
|
fi
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
65
|
+
|
|
66
|
+
# Explicitly touch the etag file to update its modification time only if successful
|
|
67
|
+
touch "$etag_file"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# Function to verify checksums
|
|
71
|
+
function verify_checksums {
|
|
72
|
+
local archive=$1
|
|
73
|
+
local header=$2
|
|
74
|
+
local sums=$3
|
|
75
|
+
|
|
76
|
+
# Determine the available SHA hashing utility
|
|
77
|
+
if command -v sha256sum &> /dev/null; then
|
|
78
|
+
sha_cmd="sha256sum"
|
|
79
|
+
elif command -v shasum &> /dev/null; then
|
|
80
|
+
sha_cmd="shasum -a 256"
|
|
40
81
|
else
|
|
41
|
-
echo "
|
|
82
|
+
echo "Error: Neither sha256sum nor shasum is available on this system." >&2
|
|
83
|
+
exit 1 # Exit since this is fatal
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [[ ! -f "${sums}" ]]; then
|
|
87
|
+
echo "Error: Checksum file '${sums}' does not exist." >&2
|
|
88
|
+
rm -f ./*.a ./*.h ./*.etag
|
|
89
|
+
return 1
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Filter the relevant checksums and verify they are not empty
|
|
93
|
+
checksums=$(grep -e "${archive}" -e "${header}" "${sums}")
|
|
94
|
+
if [[ -z "$checksums" ]]; then
|
|
95
|
+
echo "Error: No matching checksums found for ${archive} or ${header} in ${sums}." >&2
|
|
96
|
+
return 1
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
echo "$checksums" > ./SHA256SUM # Return value
|
|
100
|
+
|
|
101
|
+
if ! $sha_cmd -c ./SHA256SUM; then
|
|
102
|
+
echo 'SHA256 mismatch!' >&2
|
|
103
|
+
rm -f ./*.a ./*.h
|
|
104
|
+
return 1
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Function to copy library and header files
|
|
109
|
+
function copy_files {
|
|
110
|
+
local archive=$1
|
|
111
|
+
local header=$2
|
|
112
|
+
|
|
113
|
+
if [[ ! -f "${archive}" ]]; then
|
|
114
|
+
echo "Error: Source archive file '${archive}' does not exist." >&2
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
if [[ ! -f "${header}" ]]; then
|
|
119
|
+
echo "Error: Source header file '${header}' does not exist." >&2
|
|
42
120
|
exit 1
|
|
43
121
|
fi
|
|
44
|
-
else
|
|
45
|
-
echo "Unsupported operating system"
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
122
|
|
|
49
|
-
|
|
123
|
+
if ! cp -f "${archive}" libasherah.a; then
|
|
124
|
+
echo "Error: Failed to copy archive file '${archive}' to 'libasherah.a'." >&2
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
if ! cp -f "${header}" libasherah.h; then
|
|
129
|
+
echo "Error: Failed to copy header file '${header}' to 'libasherah.h'." >&2
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Function to detect OS and CPU architecture
|
|
135
|
+
function detect_os_and_cpu {
|
|
136
|
+
OS=$(uname)
|
|
137
|
+
MACHINE=$(uname -m)
|
|
138
|
+
|
|
139
|
+
#echo "Detected OS: ${OS}"
|
|
140
|
+
#echo "Detected CPU architecture: ${MACHINE}"
|
|
141
|
+
|
|
142
|
+
if [[ "${OS}" == 'Linux' ]]; then
|
|
143
|
+
if [[ ${MACHINE} == 'x86_64' ]]; then
|
|
144
|
+
#echo "Using Asherah libraries for Linux x86_64"
|
|
145
|
+
ARCHIVE="libasherah-x64.a"
|
|
146
|
+
HEADER="libasherah-x64-archive.h"
|
|
147
|
+
SUMS="SHA256SUMS"
|
|
148
|
+
elif [[ ${MACHINE} == 'aarch64' ]]; then
|
|
149
|
+
#echo "Using Asherah libraries for Linux aarch64"
|
|
150
|
+
ARCHIVE="libasherah-arm64.a"
|
|
151
|
+
HEADER="libasherah-arm64-archive.h"
|
|
152
|
+
SUMS="SHA256SUMS"
|
|
153
|
+
else
|
|
154
|
+
#echo "Unsupported CPU architecture: ${MACHINE}" >&2
|
|
155
|
+
exit 1
|
|
156
|
+
fi
|
|
157
|
+
elif [[ "${OS}" == 'Darwin' ]]; then
|
|
158
|
+
if [[ ${MACHINE} == 'x86_64' ]]; then
|
|
159
|
+
#echo "Using Asherah libraries for MacOS x86_64"
|
|
160
|
+
ARCHIVE="libasherah-darwin-x64.a"
|
|
161
|
+
HEADER="libasherah-darwin-x64-archive.h"
|
|
162
|
+
SUMS="SHA256SUMS-darwin"
|
|
163
|
+
elif [[ ${MACHINE} == 'arm64' ]]; then
|
|
164
|
+
#echo "Using Asherah libraries for MacOS arm64"
|
|
165
|
+
ARCHIVE="libasherah-darwin-arm64.a"
|
|
166
|
+
HEADER="libasherah-darwin-arm64-archive.h"
|
|
167
|
+
SUMS="SHA256SUMS-darwin"
|
|
168
|
+
else
|
|
169
|
+
echo "Unsupported CPU architecture: ${MACHINE}" >&2
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
else
|
|
173
|
+
echo "Unsupported operating system: ${OS}" >&2
|
|
174
|
+
exit 1
|
|
175
|
+
fi
|
|
50
176
|
|
|
51
|
-
|
|
177
|
+
echo "${ARCHIVE}" "${HEADER}" "${SUMS}" # Return value
|
|
178
|
+
}
|
|
52
179
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
180
|
+
# Parse script arguments
|
|
181
|
+
function parse_args {
|
|
182
|
+
local no_cache=false
|
|
183
|
+
while [[ $# -gt 0 ]]; do
|
|
184
|
+
case "$1" in
|
|
185
|
+
--no-cache)
|
|
186
|
+
no_cache=true
|
|
187
|
+
shift
|
|
188
|
+
;;
|
|
189
|
+
*)
|
|
190
|
+
echo "Unknown parameter: $1" >&2
|
|
191
|
+
exit 1
|
|
192
|
+
;;
|
|
193
|
+
esac
|
|
194
|
+
done
|
|
195
|
+
echo "${no_cache}" # Return value
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
# Function to determine the interval message
|
|
199
|
+
function interval_message {
|
|
200
|
+
local interval=$1
|
|
201
|
+
if (( interval % 60 == 0 )); then
|
|
202
|
+
echo "$((interval / 60)) minutes" # Return value
|
|
203
|
+
else
|
|
204
|
+
echo "$interval seconds" # Return value
|
|
205
|
+
fi
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# Main function
|
|
209
|
+
function main {
|
|
210
|
+
echo "Downloading Asherah libraries"
|
|
211
|
+
# shellcheck disable=SC1091
|
|
212
|
+
source .asherah-version
|
|
213
|
+
|
|
214
|
+
# Parse arguments
|
|
215
|
+
local no_cache
|
|
216
|
+
no_cache=$(parse_args "$@")
|
|
217
|
+
|
|
218
|
+
# Detect OS and CPU architecture
|
|
219
|
+
read -r archive header sums < <(detect_os_and_cpu)
|
|
220
|
+
echo "Archive: $archive"
|
|
221
|
+
echo "Header: $header"
|
|
222
|
+
echo "Sums: $sums"
|
|
223
|
+
echo "Version: $ASHERAH_VERSION"
|
|
224
|
+
|
|
225
|
+
# Interpolate the URLs
|
|
226
|
+
url_prefix="https://github.com/godaddy/asherah-cobhan/releases/download/${ASHERAH_VERSION}"
|
|
227
|
+
file_names=("${archive}" "${header}" "${sums}")
|
|
228
|
+
file_urls=(
|
|
229
|
+
"${url_prefix}/${archive}"
|
|
230
|
+
"${url_prefix}/${header}"
|
|
231
|
+
"${url_prefix}/${sums}"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
# Create the `lib` directory if it doesn't exist
|
|
235
|
+
mkdir -p lib
|
|
236
|
+
cd lib || exit 1
|
|
237
|
+
|
|
238
|
+
local retries=0
|
|
239
|
+
local checksums_verified=false
|
|
240
|
+
while [[ $checksums_verified == false && $retries -lt $MAX_DOWNLOAD_RETRIES ]]; do
|
|
241
|
+
# Per-file touch and download logic
|
|
242
|
+
for i in "${!file_names[@]}"; do
|
|
243
|
+
if check_download_required "${file_names[$i]}" "$no_cache" "$CHECK_INTERVAL_SECONDS"; then
|
|
244
|
+
download_file "${file_urls[$i]}" "${file_names[$i]}"
|
|
245
|
+
else
|
|
246
|
+
interval_str=$(interval_message "$CHECK_INTERVAL_SECONDS")
|
|
247
|
+
echo "${file_names[$i]} is up to date (checked within the last ${interval_str})"
|
|
248
|
+
fi
|
|
249
|
+
done
|
|
250
|
+
|
|
251
|
+
# Verify checksums and copy files
|
|
252
|
+
if verify_checksums "${archive}" "${header}" "${sums}"; then
|
|
253
|
+
copy_files "${archive}" "${header}"
|
|
254
|
+
checksums_verified=true
|
|
255
|
+
else
|
|
256
|
+
echo "Verification failed, re-downloading files..."
|
|
257
|
+
((retries++))
|
|
258
|
+
# Sleep for a bit before retrying to avoid hammering the server
|
|
259
|
+
sleep 1
|
|
260
|
+
fi
|
|
261
|
+
done
|
|
262
|
+
|
|
263
|
+
if [[ $checksums_verified == true ]]; then
|
|
264
|
+
copy_files "${archive}" "${header}"
|
|
265
|
+
echo "Asherah libraries downloaded successfully"
|
|
266
|
+
else
|
|
267
|
+
echo "Failed to download Asherah libraries after $retries retries."
|
|
268
|
+
exit 1
|
|
269
|
+
fi
|
|
270
|
+
}
|
|
56
271
|
|
|
57
|
-
|
|
58
|
-
|
|
272
|
+
# Execute the main function
|
|
273
|
+
main "$@"
|