src: include crypto in the bootstrap snapshot

To lazy load the run time options, the following properties
are updated from value properties to accessor properties
whose getter would turn them back to a value properties
upon the initial access.

- crypto.constants.defaultCipherList
- crypto.pseudoRandomBytes
- crypto.prng
- crypto.rng

PR-URL: https://github.com/nodejs/node/pull/42203
Refs: https://github.com/nodejs/node/issues/37476
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Joyee Cheung 2022-03-04 02:18:56 +08:00 committed by Node.js GitHub Bot
parent de163d5db6
commit 457567f72c
7 changed files with 110 additions and 41 deletions

View File

@ -40,8 +40,6 @@ const {
} = require('internal/errors').codes;
const constants = internalBinding('constants').crypto;
const { getOptionValue } = require('internal/options');
const pendingDeprecation = getOptionValue('--pending-deprecation');
const fipsForced = getOptionValue('--force-fips');
const {
getFipsCrypto,
setFipsCrypto,
@ -221,8 +219,8 @@ module.exports = {
sign: signOneShot,
setEngine,
timingSafeEqual,
getFips: fipsForced ? getFipsForced : getFipsCrypto,
setFips: fipsForced ? setFipsForced : setFipsCrypto,
getFips,
setFips,
verify: verifyOneShot,
// Classes
@ -243,13 +241,17 @@ module.exports = {
secureHeapUsed,
};
function setFipsForced(val) {
if (val) return;
throw new ERR_CRYPTO_FIPS_FORCED();
function getFips() {
return getOptionValue('--force-fips') ? 1 : getFipsCrypto();
}
function getFipsForced() {
return 1;
function setFips(val) {
if (getOptionValue('--force-fips')) {
if (val) return;
throw new ERR_CRYPTO_FIPS_FORCED();
} else {
setFipsCrypto(val);
}
}
function getRandomValues(array) {
@ -257,9 +259,69 @@ function getRandomValues(array) {
}
ObjectDefineProperty(constants, 'defaultCipherList', {
value: getOptionValue('--tls-cipher-list')
get() {
const value = getOptionValue('--tls-cipher-list');
ObjectDefineProperty(this, 'defaultCipherList', {
writable: true,
configurable: true,
enumerable: true,
value
});
return value;
},
set(val) {
ObjectDefineProperty(this, 'defaultCipherList', {
writable: true,
configurable: true,
enumerable: true,
value: val
});
},
configurable: true,
enumerable: true,
});
function getRandomBytesAlias(key) {
return {
enumerable: false,
configurable: true,
get() {
let value;
if (getOptionValue('--pending-deprecation')) {
value = deprecate(
randomBytes,
`crypto.${key} is deprecated.`,
'DEP0115');
} else {
value = randomBytes;
}
ObjectDefineProperty(
this,
key,
{
enumerable: false,
configurable: true,
writable: true,
value: value
}
);
return value;
},
set(value) {
ObjectDefineProperty(
this,
key,
{
enumerable: true,
configurable: true,
writable: true,
value
}
);
}
};
}
ObjectDefineProperties(module.exports, {
createCipher: {
enumerable: false,
@ -273,8 +335,8 @@ ObjectDefineProperties(module.exports, {
},
// crypto.fips is deprecated. DEP0093. Use crypto.getFips()/crypto.setFips()
fips: {
get: fipsForced ? getFipsForced : getFipsCrypto,
set: fipsForced ? setFipsForced : setFipsCrypto
get: getFips,
set: setFips,
},
DEFAULT_ENCODING: {
enumerable: false,
@ -313,29 +375,7 @@ ObjectDefineProperties(module.exports, {
// Aliases for randomBytes are deprecated.
// The ecosystem needs those to exist for backwards compatibility.
prng: {
enumerable: false,
configurable: true,
writable: true,
value: pendingDeprecation ?
deprecate(randomBytes, 'crypto.prng is deprecated.', 'DEP0115') :
randomBytes
},
pseudoRandomBytes: {
enumerable: false,
configurable: true,
writable: true,
value: pendingDeprecation ?
deprecate(randomBytes,
'crypto.pseudoRandomBytes is deprecated.', 'DEP0115') :
randomBytes
},
rng: {
enumerable: false,
configurable: true,
writable: true,
value: pendingDeprecation ?
deprecate(randomBytes, 'crypto.rng is deprecated.', 'DEP0115') :
randomBytes
}
prng: getRandomBytesAlias('prng'),
pseudoRandomBytes: getRandomBytesAlias('pseudoRandomBytes'),
rng: getRandomBytesAlias('rng')
});

View File

@ -339,6 +339,9 @@ require('v8');
require('vm');
require('url');
require('internal/options');
if (config.hasOpenSSL) {
require('crypto');
}
function setupPrepareStackTrace() {
const {

View File

@ -61,7 +61,6 @@ const {
const { isArrayBufferView } = require('internal/util/types');
const { getOptionValue } = require('internal/options');
const pendingDeprecation = getOptionValue('--pending-deprecation');
function wrapKey(key, ctor) {
if (typeof key === 'string' ||
@ -199,6 +198,9 @@ function createJob(mode, type, options) {
const {
hash, mgf1Hash, hashAlgorithm, mgf1HashAlgorithm, saltLength
} = options;
const pendingDeprecation = getOptionValue('--pending-deprecation');
if (saltLength !== undefined && (!isInt32(saltLength) || saltLength < 0))
throw new ERR_INVALID_ARG_VALUE('options.saltLength', saltLength);
if (hashAlgorithm !== undefined && typeof hashAlgorithm !== 'string')

View File

@ -75,8 +75,6 @@ void Initialize(Local<Object> target,
void* priv) {
Environment* env = Environment::GetCurrent(context);
// TODO(joyeecheung): this needs to be called again if the instance is
// deserialized from a snapshot with the crypto bindings.
if (!InitCryptoOnce(env->isolate())) {
return;
}

View File

@ -1,5 +1,8 @@
#include "node_main_instance.h"
#include <memory>
#if HAVE_OPENSSL
#include "crypto/crypto_util.h"
#endif // HAVE_OPENSSL
#include "debug_utils-inl.h"
#include "node_external_reference.h"
#include "node_internals.h"
@ -205,6 +208,10 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code,
env->InitializeInspector({});
#endif
env->DoneBootstrapping();
#if HAVE_OPENSSL
crypto::InitCryptoOnce(isolate_);
#endif // HAVE_OPENSSL
} else {
context = NewContext(isolate_);
CHECK(!context.IsEmpty());

View File

@ -206,6 +206,26 @@ if (process.env.NODE_V8_COVERAGE) {
expectedModules.add('Internal Binding profiler');
}
if (common.hasCrypto) {
expectedModules.add('Internal Binding crypto');
expectedModules.add('NativeModule crypto');
expectedModules.add('NativeModule internal/crypto/certificate');
expectedModules.add('NativeModule internal/crypto/cipher');
expectedModules.add('NativeModule internal/crypto/diffiehellman');
expectedModules.add('NativeModule internal/crypto/hash');
expectedModules.add('NativeModule internal/crypto/hashnames');
expectedModules.add('NativeModule internal/crypto/hkdf');
expectedModules.add('NativeModule internal/crypto/keygen');
expectedModules.add('NativeModule internal/crypto/keys');
expectedModules.add('NativeModule internal/crypto/pbkdf2');
expectedModules.add('NativeModule internal/crypto/random');
expectedModules.add('NativeModule internal/crypto/scrypt');
expectedModules.add('NativeModule internal/crypto/sig');
expectedModules.add('NativeModule internal/crypto/util');
expectedModules.add('NativeModule internal/crypto/x509');
expectedModules.add('NativeModule internal/streams/lazy_transform');
}
const { internalBinding } = require('internal/test/binding');
if (internalBinding('config').hasDtrace) {
expectedModules.add('Internal Binding dtrace');

View File

@ -338,7 +338,6 @@ assert.throws(
const desc = Object.getOwnPropertyDescriptor(crypto, f);
assert.ok(desc);
assert.strictEqual(desc.configurable, true);
assert.strictEqual(desc.writable, true);
assert.strictEqual(desc.enumerable, false);
});