Skip to content
114 changes: 77 additions & 37 deletions lib/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -221,8 +219,8 @@ module.exports = {
sign: signOneShot,
setEngine,
timingSafeEqual,
getFips: fipsForced ? getFipsForced : getFipsCrypto,
setFips: fipsForced ? setFipsForced : setFipsCrypto,
getFips,
setFips,
verify: verifyOneShot,

// Classes
Expand All @@ -243,23 +241,87 @@ 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) {
return lazyWebCrypto().crypto.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,
Expand All @@ -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,
Expand Down Expand Up @@ -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')
});
4 changes: 4 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ require('fs');
require('v8');
require('vm');
require('url');
require('internal/options');
if (config.hasOpenSSL) {
require('crypto');
}

function setupPrepareStackTrace() {
const {
Expand Down
4 changes: 3 additions & 1 deletion lib/internal/crypto/keygen.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' ||
Expand Down Expand Up @@ -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')
Expand Down
2 changes: 0 additions & 2 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class ExternalReferenceRegistry {
V(heap_utils) \
V(messaging) \
V(native_module) \
V(options) \
V(os) \
V(performance) \
V(process_methods) \
Expand Down
7 changes: 7 additions & 0 deletions src/node_main_instance.cc
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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());
Expand Down
7 changes: 7 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "env-inl.h"
#include "node_binding.h"
#include "node_external_reference.h"
#include "node_internals.h"
#if HAVE_OPENSSL
#include "openssl/opensslv.h"
Expand Down Expand Up @@ -1133,6 +1134,10 @@ void Initialize(Local<Object> target,
.Check();
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetCLIOptions);
registry->Register(GetEmbedderOptions);
}
} // namespace options_parser

void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options) {
Expand Down Expand Up @@ -1199,3 +1204,5 @@ std::vector<std::string> ParseNodeOptionsEnvVar(
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(options, node::options_parser::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(options,
node::options_parser::RegisterExternalReferences)
20 changes: 20 additions & 0 deletions test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
1 change: 0 additions & 1 deletion test/parallel/test-crypto-random.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});

Expand Down