| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 42aca13 commit 53cf996
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -848,6 +848,40 @@ Enables report to be generated on uncaught exceptions. Useful when inspecting | |||
| 848 | 848 | the JavaScript stack in conjunction with native stack and other runtime | |
| 849 | 849 | environment data. | |
| 850 | 850 | ||
| 851 | + ### `--secure-heap=n` | ||
| 852 | + <!-- YAML | ||
| 853 | + added: REPLACEME | ||
| 854 | + --> | ||
| 855 | + | ||
| 856 | + Initializes an OpenSSL secure heap of `n` bytes. When initialized, the | ||
| 857 | + secure heap is used for selected types of allocations within OpenSSL | ||
| 858 | + during key generation and other operations. This is useful, for instance, | ||
| 859 | + to prevent sensitive information from leaking due to pointer overruns | ||
| 860 | + or underruns. | ||
| 861 | + | ||
| 862 | + The secure heap is a fixed size and cannot be resized at runtime so, | ||
| 863 | + if used, it is important to select a large enough heap to cover all | ||
| 864 | + application uses. | ||
| 865 | + | ||
| 866 | + The heap size given must be a power of two. Any value less than 2 | ||
| 867 | + will disable the secure heap. | ||
| 868 | + | ||
| 869 | + The secure heap is disabled by default. | ||
| 870 | + | ||
| 871 | + The secure heap is not available on Windows. | ||
| 872 | + | ||
| 873 | + See [`CRYPTO_secure_malloc_init`][] for more details. | ||
| 874 | + | ||
| 875 | + ### `--secure-heap-min=n` | ||
| 876 | + <!-- YAML | ||
| 877 | + added: REPLACEME | ||
| 878 | + --> | ||
| 879 | + | ||
| 880 | + When using `--secure-heap`, the `--secure-heap-min` flag specifies the | ||
| 881 | + minimum allocation from the secure heap. The minimum value is `2`. | ||
| 882 | + The maximum value is the lesser of `--secure-heap` or `2147483647`. | ||
| 883 | + The value given must be a power of two. | ||
| 884 | + | ||
| 851 | 885 | ### `--throw-deprecation` | |
| 852 | 886 | <!-- YAML | |
| 853 | 887 | added: v0.11.14 | |
@@ -1361,6 +1395,8 @@ Node.js options that are allowed are: | |||
| 1361 | 1395 | * `--report-signal` | |
| 1362 | 1396 | * `--report-uncaught-exception` | |
| 1363 | 1397 | * `--require`, `-r` | |
| 1398 | + * `--secure-heap-min` | ||
| 1399 | + * `--secure-heap` | ||
| 1364 | 1400 | * `--throw-deprecation` | |
| 1365 | 1401 | * `--title` | |
| 1366 | 1402 | * `--tls-cipher-list` | |
@@ -1659,6 +1695,7 @@ $ node --max-old-space-size=1536 index.js | |||
| 1659 | 1695 | [`--openssl-config`]: #cli_openssl_config_file | |
| 1660 | 1696 | [`Atomics.wait()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait | |
| 1661 | 1697 | [`Buffer`]: buffer.md#buffer_class_buffer | |
| 1698 | + [`CRYPTO_secure_malloc_init`]: https://www.openssl.org/docs/man1.1.0/man3/CRYPTO_secure_malloc_init.html | ||
| 1662 | 1699 | [`NODE_OPTIONS`]: #cli_node_options_options | |
| 1663 | 1700 | [`SlowBuffer`]: buffer.md#buffer_class_slowbuffer | |
| 1664 | 1701 | [`process.setUncaughtExceptionCaptureCallback()`]: process.md#process_process_setuncaughtexceptioncapturecallback_fn | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3545,6 +3545,21 @@ const key2 = crypto.scryptSync('password', 'salt', 64, { N: 1024 }); | |||
| 3545 | 3545 | console.log(key2.toString('hex')); // '3745e48...aa39b34' | |
| 3546 | 3546 | ``` | |
| 3547 | 3547 | ||
| 3548 | + ### `crypto.secureHeapUsed()` | ||
| 3549 | + <!-- YAML | ||
| 3550 | + added: REPLACEME | ||
| 3551 | + --> | ||
| 3552 | + | ||
| 3553 | + * Returns: {Object} | ||
| 3554 | + * `total` {number} The total allocated secure heap size as specified | ||
| 3555 | + using the `--secure-heap=n` command-line flag. | ||
| 3556 | + * `min` {number} The minimum allocation from the secure heap as | ||
| 3557 | + specified using the `--secure-heap-min` command-line flag. | ||
| 3558 | + * `used` {number} The total number of bytes currently allocated from | ||
| 3559 | + the secure heap. | ||
| 3560 | + * `utilization` {number} The calculated ratio of `used` to `total` | ||
| 3561 | + allocated bytes. | ||
| 3562 | + | ||
| 3548 | 3563 | ### `crypto.setEngine(engine[, flags])` | |
| 3549 | 3564 | <!-- YAML | |
| 3550 | 3565 | added: v0.11.11 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -359,6 +359,13 @@ Enables | |||
| 359 | 359 | to be generated on un-caught exceptions. Useful when inspecting JavaScript | |
| 360 | 360 | stack in conjunction with native stack and other runtime environment data. | |
| 361 | 361 | . | |
| 362 | + .It Fl -secure-heap Ns = Ns Ar n | ||
| 363 | + Specify the size of the OpenSSL secure heap. Any value less than 2 disables | ||
| 364 | + the secure heap. The default is 0. The value must be a power of two. | ||
| 365 | + . | ||
| 366 | + .It Fl -secure-heap-min Ns = Ns Ar n | ||
| 367 | + Specify the minimum allocation from the OpenSSL secure heap. The default is 2. The value must be a power of two. | ||
| 368 | + . | ||
| 362 | 369 | .It Fl -throw-deprecation | |
| 363 | 370 | Throw errors for deprecations. | |
| 364 | 371 | . | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -118,6 +118,7 @@ const { | |||
| 118 | 118 | setDefaultEncoding, | |
| 119 | 119 | setEngine, | |
| 120 | 120 | lazyRequire, | |
| 121 | + secureHeapUsed, | ||
| 121 | 122 | } = require('internal/crypto/util'); | |
| 122 | 123 | const Certificate = require('internal/crypto/certificate'); | |
| 123 | 124 | ||
@@ -230,6 +231,7 @@ module.exports = { | |||
| 230 | 231 | Sign, | |
| 231 | 232 | Verify, | |
| 232 | 233 | X509Certificate, | |
| 234 | + secureHeapUsed, | ||
| 233 | 235 | }; | |
| 234 | 236 | ||
| 235 | 237 | function setFipsDisabled() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,7 @@ const { | |||
| 4 | 4 | ArrayPrototypeIncludes, | |
| 5 | 5 | ArrayPrototypePush, | |
| 6 | 6 | FunctionPrototypeBind, | |
| 7 | + Number, | ||
| 7 | 8 | Promise, | |
| 8 | 9 | StringPrototypeToLowerCase, | |
| 9 | 10 | StringPrototypeToUpperCase, | |
@@ -15,8 +16,11 @@ const { | |||
| 15 | 16 | getCurves: _getCurves, | |
| 16 | 17 | getHashes: _getHashes, | |
| 17 | 18 | setEngine: _setEngine, | |
| 19 | + secureHeapUsed: _secureHeapUsed, | ||
| 18 | 20 | } = internalBinding('crypto'); | |
| 19 | 21 | ||
| 22 | + const { getOptionValue } = require('internal/options'); | ||
| 23 | + | ||
| 20 | 24 | const { | |
| 21 | 25 | crypto: { | |
| 22 | 26 | ENGINE_METHOD_ALL | |
@@ -371,6 +375,17 @@ function validateKeyOps(keyOps, usagesSet) { | |||
| 371 | 375 | } | |
| 372 | 376 | } | |
| 373 | 377 | ||
| 378 | + function secureHeapUsed() { | ||
| 379 | + const val = _secureHeapUsed(); | ||
| 380 | + if (val === undefined) | ||
| 381 | + return { total: 0, used: 0, utilization: 0, min: 0 }; | ||
| 382 | + const used = Number(_secureHeapUsed()); | ||
| 383 | + const total = Number(getOptionValue('--secure-heap')); | ||
| 384 | + const min = Number(getOptionValue('--secure-heap-min')); | ||
| 385 | + const utilization = used / total; | ||
| 386 | + return { total, used, utilization, min }; | ||
| 387 | + } | ||
| 388 | + | ||
| 374 | 389 | module.exports = { | |
| 375 | 390 | getArrayBufferOrView, | |
| 376 | 391 | getCiphers, | |
@@ -402,4 +417,5 @@ module.exports = { | |||
| 402 | 417 | getStringOption, | |
| 403 | 418 | getUsagesUnion, | |
| 404 | 419 | getHashLength, | |
| 420 | + secureHeapUsed, | ||
| 405 | 421 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,7 @@ namespace node { | |||
| 18 | 18 | ||
| 19 | 19 | using v8::ArrayBuffer; | |
| 20 | 20 | using v8::BackingStore; | |
| 21 | + using v8::BigInt; | ||
| 21 | 22 | using v8::Context; | |
| 22 | 23 | using v8::Exception; | |
| 23 | 24 | using v8::FunctionCallbackInfo; | |
@@ -113,6 +114,25 @@ void InitCryptoOnce() { | |||
| 113 | 114 | settings = nullptr; | |
| 114 | 115 | #endif | |
| 115 | 116 | ||
| 117 | + #ifndef _WIN32 | ||
| 118 | + if (per_process::cli_options->secure_heap != 0) { | ||
| 119 | + switch (CRYPTO_secure_malloc_init( | ||
| 120 | + per_process::cli_options->secure_heap, | ||
| 121 | + static_cast<int>(per_process::cli_options->secure_heap_min))) { | ||
| 122 | + case 0: | ||
| 123 | + fprintf(stderr, "Unable to initialize openssl secure heap.\n"); | ||
| 124 | + break; | ||
| 125 | + case 2: | ||
| 126 | + // Not a fatal error but worthy of a warning. | ||
| 127 | + fprintf(stderr, "Unable to memory map openssl secure heap.\n"); | ||
| 128 | + break; | ||
| 129 | + case 1: | ||
| 130 | + // OK! | ||
| 131 | + break; | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + #endif | ||
| 135 | + | ||
| 116 | 136 | #ifdef NODE_FIPS_MODE | |
| 117 | 137 | /* Override FIPS settings in cnf file, if needed. */ | |
| 118 | 138 | unsigned long err = 0; // NOLINT(runtime/int) | |
@@ -617,6 +637,13 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) { | |||
| 617 | 637 | Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store); | |
| 618 | 638 | args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len)); | |
| 619 | 639 | } | |
| 640 | + | ||
| 641 | + void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) { | ||
| 642 | + Environment* env = Environment::GetCurrent(args); | ||
| 643 | + if (CRYPTO_secure_malloc_initialized()) | ||
| 644 | + args.GetReturnValue().Set( | ||
| 645 | + BigInt::New(env->isolate(), CRYPTO_secure_used())); | ||
| 646 | + } | ||
| 620 | 647 | } // namespace | |
| 621 | 648 | ||
| 622 | 649 | namespace Util { | |
@@ -634,6 +661,7 @@ void Initialize(Environment* env, Local<Object> target) { | |||
| 634 | 661 | NODE_DEFINE_CONSTANT(target, kCryptoJobSync); | |
| 635 | 662 | ||
| 636 | 663 | env->SetMethod(target, "secureBuffer", SecureBuffer); | |
| 664 | + env->SetMethod(target, "secureHeapUsed", SecureHeapUsed); | ||
| 637 | 665 | } | |
| 638 | 666 | } // namespace Util | |
| 639 | 667 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | 8 | #include <errno.h> | |
| 9 | 9 | #include <sstream> | |
| 10 | + #include <limits> | ||
| 11 | + #include <algorithm> | ||
| 10 | 12 | #include <cstdlib> // strtoul, errno | |
| 11 | 13 | ||
| 12 | 14 | using v8::Boolean; | |
@@ -64,6 +66,20 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors) { | |||
| 64 | 66 | errors->push_back("either --use-openssl-ca or --use-bundled-ca can be " | |
| 65 | 67 | "used, not both"); | |
| 66 | 68 | } | |
| 69 | + | ||
| 70 | + // Any value less than 2 disables use of the secure heap. | ||
| 71 | + if (secure_heap >= 2) { | ||
| 72 | + if ((secure_heap & (secure_heap - 1)) != 0) | ||
| 73 | + errors->push_back("--secure-heap must be a power of 2"); | ||
| 74 | + secure_heap_min = | ||
| 75 | + std::min({ | ||
| 76 | + secure_heap, | ||
| 77 | + secure_heap_min, | ||
| 78 | + static_cast<int64_t>(std::numeric_limits<int>::max())}); | ||
| 79 | + secure_heap_min = std::max(static_cast<int64_t>(2), secure_heap_min); | ||
| 80 | + if ((secure_heap_min & (secure_heap_min - 1)) != 0) | ||
| 81 | + errors->push_back("--secure-heap-min must be a power of 2"); | ||
| 82 | + } | ||
| 67 | 83 | #endif | |
| 68 | 84 | if (use_largepages != "off" && | |
| 69 | 85 | use_largepages != "on" && | |
@@ -760,6 +776,14 @@ PerProcessOptionsParser::PerProcessOptionsParser( | |||
| 760 | 776 | &PerProcessOptions::force_fips_crypto, | |
| 761 | 777 | kAllowedInEnvironment); | |
| 762 | 778 | #endif | |
| 779 | + AddOption("--secure-heap", | ||
| 780 | + "total size of the OpenSSL secure heap", | ||
| 781 | + &PerProcessOptions::secure_heap, | ||
| 782 | + kAllowedInEnvironment); | ||
| 783 | + AddOption("--secure-heap-min", | ||
| 784 | + "minimum allocation size from the OpenSSL secure heap", | ||
| 785 | + &PerProcessOptions::secure_heap_min, | ||
| 786 | + kAllowedInEnvironment); | ||
| 763 | 787 | #endif | |
| 764 | 788 | AddOption("--use-largepages", | |
| 765 | 789 | "Map the Node.js static code to large pages. Options are " | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -236,6 +236,8 @@ class PerProcessOptions : public Options { | |||
| 236 | 236 | #if HAVE_OPENSSL | |
| 237 | 237 | std::string openssl_config; | |
| 238 | 238 | std::string tls_cipher_list = DEFAULT_CIPHER_LIST_CORE; | |
| 239 | + int64_t secure_heap = 0; | ||
| 240 | + int64_t secure_heap_min = 2; | ||
| 239 | 241 | #ifdef NODE_OPENSSL_CERT_STORE | |
| 240 | 242 | bool ssl_openssl_cert_store = true; | |
| 241 | 243 | #else | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,72 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + if (!common.hasCrypto) | ||
| 5 | + common.skip('missing crypto'); | ||
| 6 | + | ||
| 7 | + if (common.isWindows) | ||
| 8 | + common.skip('Not supported on Windows'); | ||
| 9 | + | ||
| 10 | + const assert = require('assert'); | ||
| 11 | + const { fork } = require('child_process'); | ||
| 12 | + const fixtures = require('../common/fixtures'); | ||
| 13 | + const { | ||
| 14 | + secureHeapUsed, | ||
| 15 | + createDiffieHellman, | ||
| 16 | + } = require('crypto'); | ||
| 17 | + | ||
| 18 | + if (process.argv[2] === 'child') { | ||
| 19 | + | ||
| 20 | + const a = secureHeapUsed(); | ||
| 21 | + | ||
| 22 | + assert(a); | ||
| 23 | + assert.strictEqual(typeof a, 'object'); | ||
| 24 | + assert.strictEqual(a.total, 65536); | ||
| 25 | + assert.strictEqual(a.min, 4); | ||
| 26 | + assert.strictEqual(a.used, 0); | ||
| 27 | + | ||
| 28 | + { | ||
| 29 | + const dh1 = createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); | ||
| 30 | + const p1 = dh1.getPrime('buffer'); | ||
| 31 | + const dh2 = createDiffieHellman(p1, 'buffer'); | ||
| 32 | + const key1 = dh1.generateKeys(); | ||
| 33 | + const key2 = dh2.generateKeys('hex'); | ||
| 34 | + dh1.computeSecret(key2, 'hex', 'base64'); | ||
| 35 | + dh2.computeSecret(key1, 'latin1', 'buffer'); | ||
| 36 | + | ||
| 37 | + const b = secureHeapUsed(); | ||
| 38 | + assert(b); | ||
| 39 | + assert.strictEqual(typeof b, 'object'); | ||
| 40 | + assert.strictEqual(b.total, 65536); | ||
| 41 | + assert.strictEqual(b.min, 4); | ||
| 42 | + // The amount used can vary on a number of factors | ||
| 43 | + assert(b.used > 0); | ||
| 44 | + assert(b.utilization > 0.0); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + return; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + const child = fork( | ||
| 51 | + process.argv[1], | ||
| 52 | + ['child'], | ||
| 53 | + { execArgv: ['--secure-heap=65536', '--secure-heap-min=4'] }); | ||
| 54 | + | ||
| 55 | + child.on('exit', common.mustCall((code) => { | ||
| 56 | + assert.strictEqual(code, 0); | ||
| 57 | + })); | ||
| 58 | + | ||
| 59 | + { | ||
| 60 | + const child = fork(fixtures.path('a.js'), { | ||
| 61 | + execArgv: ['--secure-heap=3', '--secure-heap-min=3'], | ||
| 62 | + stdio: 'pipe' | ||
| 63 | + }); | ||
| 64 | + let res = ''; | ||
| 65 | + child.on('exit', common.mustCall((code) => { | ||
| 66 | + assert.notStrictEqual(code, 0); | ||
| 67 | + assert.match(res, /--secure-heap must be a power of 2/); | ||
| 68 | + assert.match(res, /--secure-heap-min must be a power of 2/); | ||
| 69 | + })); | ||
| 70 | + child.stderr.setEncoding('utf8'); | ||
| 71 | + child.stderr.on('data', (chunk) => res += chunk); | ||
| 72 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,8 +43,14 @@ for (const line of [...nodeOptionsLines, ...v8OptionsLines]) { | |||
| 43 | 43 | const conditionalOpts = [ | |
| 44 | 44 | { include: common.hasCrypto, | |
| 45 | 45 | filter: (opt) => { | |
| 46 | - return ['--openssl-config', '--tls-cipher-list', '--use-bundled-ca', | ||
| 47 | - '--use-openssl-ca' ].includes(opt); | ||
| 46 | + return [ | ||
| 47 | + '--openssl-config', | ||
| 48 | + '--tls-cipher-list', | ||
| 49 | + '--use-bundled-ca', | ||
| 50 | + '--use-openssl-ca', | ||
| 51 | + '--secure-heap', | ||
| 52 | + '--secure-heap-min', | ||
| 53 | + ].includes(opt); | ||
| 48 | 54 | } }, | |
| 49 | 55 | { | |
| 50 | 56 | // We are using openssl_is_fips from the configuration because it could be | |
| Back | FazBrowse Home | New Git URL |
0 commit comments