Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: use globalThis.crypto over require('crypto').webcrypto #45817

Merged
merged 1 commit into from Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.js
Expand Up @@ -239,6 +239,12 @@ module.exports = {
selector: "CallExpression[callee.name='isNaN']",
message: 'Use Number.isNaN() instead of the global isNaN() function.',
},
{
panva marked this conversation as resolved.
Show resolved Hide resolved
// TODO(@panva): move this to no-restricted-properties
// when https://github.com/eslint/eslint/issues/16412 is fixed
selector: "Identifier[name='webcrypto']",
message: 'Use `globalThis.crypto`.',
},
],
'no-return-await': 'error',
'no-self-compare': 'error',
Expand Down
9 changes: 3 additions & 6 deletions benchmark/crypto/webcrypto-digest.js
@@ -1,11 +1,8 @@
'use strict';

const common = require('../common.js');
const {
createHash,
webcrypto,
} = require('crypto');
const { subtle } = webcrypto;
const { createHash } = require('crypto');
const { subtle } = globalThis.crypto;

const bench = common.createBenchmark(main, {
sync: ['createHash', 'subtle'],
Expand Down Expand Up @@ -48,7 +45,7 @@ function measureSubtle(n, data, method) {
}

function main({ n, sync, data, method }) {
data = webcrypto.getRandomValues(Buffer.alloc(data));
data = globalThis.crypto.getRandomValues(Buffer.alloc(data));
switch (sync) {
case 'createHash': return measureLegacy(n, data, method);
case 'subtle': return measureSubtle(n, data, method);
Expand Down
12 changes: 4 additions & 8 deletions doc/api/crypto.md
Expand Up @@ -1930,8 +1930,8 @@ added: v15.0.0
Example: Converting a `CryptoKey` instance to a `KeyObject`:

```mjs
const { webcrypto, KeyObject } = await import('node:crypto');
const { subtle } = webcrypto;
const { KeyObject } = await import('node:crypto');
const { subtle } = globalThis.crypto;

const key = await subtle.generateKey({
name: 'HMAC',
Expand All @@ -1945,12 +1945,8 @@ console.log(keyObject.symmetricKeySize);
```

```cjs
const {
webcrypto: {
subtle,
},
KeyObject,
} = require('node:crypto');
const { KeyObject } = require('node:crypto');
const { subtle } = globalThis.crypto;

(async function() {
const key = await subtle.generateKey({
Expand Down
4 changes: 2 additions & 2 deletions src/crypto/README.md
Expand Up @@ -310,12 +310,12 @@ crypto.randomFill(buf, (err, buf) => {
For the legacy Node.js crypto API, asynchronous single-call
operations use the traditional Node.js callback pattern, as
illustrated in the previous `randomFill()` example. In the
Web Crypto API (accessible via `require('node:crypto').webcrypto`),
Web Crypto API (accessible via `globalThis.crypto`),
all asynchronous single-call operations are Promise-based.

```js
// Example Web Crypto API asynchronous single-call operation
const { subtle } = require('node:crypto').webcrypto;
const { subtle } = globalThis.crypto;

subtle.generateKeys({ name: 'HMAC', length: 256 }, true, ['sign'])
.then((key) => {
Expand Down
2 changes: 2 additions & 0 deletions test/.eslintrc.yaml
Expand Up @@ -49,6 +49,8 @@ rules:
message: Use 'test' as debuglog value in tests.
- selector: CallExpression:matches([callee.object.name="common"][callee.property.name=/^mustCall/],[callee.name="mustCall"],[callee.name="mustCallAtLeast"])>:first-child[type=/FunctionExpression$/][body.body.length=0]
message: Do not use an empty function, omit the parameter altogether.
- selector: Identifier[name='webcrypto']
message: Use `globalThis.crypto`.

# Custom rules in tools/eslint-rules
node-core/prefer-assert-iferror: error
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-crypto-psychic-signatures.js
Expand Up @@ -80,14 +80,14 @@ for (const [encoding, signatures] of Object.entries(vectors)) {
);

// webcrypto
crypto.webcrypto.subtle.importKey(
globalThis.crypto.subtle.importKey(
'spki',
keyPair.publicKey,
{ name: 'ECDSA', namedCurve: 'P-256' },
false,
['verify'],
).then((publicKey) => {
return crypto.webcrypto.subtle.verify(
return globalThis.crypto.subtle.verify(
{ name: 'ECDSA', hash: 'SHA-256' },
publicKey,
signature,
Expand Down
3 changes: 1 addition & 2 deletions test/parallel/test-crypto-random.js
Expand Up @@ -28,7 +28,6 @@ if (!common.hasCrypto)

const assert = require('assert');
const crypto = require('crypto');
const cryptop = require('crypto').webcrypto;
const { kMaxLength } = require('buffer');

const kMaxInt32 = 2 ** 31 - 1;
Expand Down Expand Up @@ -107,7 +106,7 @@ common.expectWarning('DeprecationWarning',
new Uint32Array(10),
].forEach((buf) => {
const before = Buffer.from(buf.buffer).toString('hex');
cryptop.getRandomValues(buf);
globalThis.crypto.getRandomValues(buf);
const after = Buffer.from(buf.buffer).toString('hex');
assert.notStrictEqual(before, after);
});
Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-crypto-subtle-zero-length.js
Expand Up @@ -6,18 +6,18 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const crypto = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;

(async () => {
const k = await crypto.subtle.importKey(
const k = await subtle.importKey(
'raw',
new Uint8Array(32),
{ name: 'AES-GCM' },
false,
[ 'encrypt', 'decrypt' ]);
assert(k instanceof CryptoKey);

const e = await crypto.subtle.encrypt({
const e = await subtle.encrypt({
name: 'AES-GCM',
iv: new Uint8Array(12),
}, k, new Uint8Array(0));
Expand All @@ -28,7 +28,7 @@ const crypto = require('crypto').webcrypto;
0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b ]));

const v = await crypto.subtle.decrypt({
const v = await subtle.decrypt({
name: 'AES-GCM',
iv: new Uint8Array(12),
}, k, e);
Expand Down
Expand Up @@ -6,9 +6,9 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const crypto = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;

crypto.subtle.importKey(
subtle.importKey(
'raw',
new Uint8Array(32),
{
Expand All @@ -18,7 +18,7 @@ crypto.subtle.importKey(
[ 'encrypt', 'decrypt' ])
.then((k) => {
assert.rejects(() => {
return crypto.subtle.decrypt({
return subtle.decrypt({
name: 'AES-GCM',
iv: new Uint8Array(12),
}, k, new Uint8Array(0));
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-global-webcrypto-classes.js
Expand Up @@ -6,8 +6,9 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const webcrypto = require('internal/crypto/webcrypto');

/* eslint-disable no-restricted-syntax */
const webcrypto = require('internal/crypto/webcrypto');
assert.strictEqual(Crypto, webcrypto.Crypto);
assert.strictEqual(CryptoKey, webcrypto.CryptoKey);
assert.strictEqual(SubtleCrypto, webcrypto.SubtleCrypto);
1 change: 1 addition & 0 deletions test/parallel/test-global-webcrypto.js
Expand Up @@ -8,6 +8,7 @@ if (!common.hasCrypto)
const assert = require('assert');
const crypto = require('crypto');

/* eslint-disable no-restricted-syntax */
assert.strictEqual(globalThis.crypto, crypto.webcrypto);
assert.strictEqual(Crypto, crypto.webcrypto.constructor);
assert.strictEqual(SubtleCrypto, crypto.webcrypto.subtle.constructor);
7 changes: 4 additions & 3 deletions test/parallel/test-webcrypto-constructors.js
Expand Up @@ -7,6 +7,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = globalThis.crypto;

// Test CryptoKey constructor
{
Expand Down Expand Up @@ -138,15 +139,15 @@ const notSubtle = Reflect.construct(function() {}, [], SubtleCrypto);
}

{
globalThis.crypto.subtle.importKey(
subtle.importKey(
'raw',
globalThis.crypto.getRandomValues(new Uint8Array(4)),
'PBKDF2',
false,
['deriveKey'],
).then((key) => {
globalThis.crypto.subtle.importKey = common.mustNotCall();
return globalThis.crypto.subtle.deriveKey({
subtle.importKey = common.mustNotCall();
return subtle.deriveKey({
name: 'PBKDF2',
hash: 'SHA-512',
salt: globalThis.crypto.getRandomValues(new Uint8Array()),
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-cryptokey-workers.js
Expand Up @@ -8,7 +8,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;
const { once } = require('events');

const {
Expand Down
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivebits-cfrg.js
Expand Up @@ -6,8 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
const { subtle } = globalThis.crypto;

const kTests = [
{
Expand Down Expand Up @@ -196,7 +195,7 @@ async function prepareKeys() {

{
// Public is a secret key
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
const key = await subtle.importKey(
'raw',
keyData,
Expand Down
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivebits-ecdh.js
Expand Up @@ -6,8 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
const { subtle } = globalThis.crypto;

const kTests = [
{
Expand Down Expand Up @@ -251,7 +250,7 @@ async function prepareKeys() {

{
// Public is a secret key
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
const key = await subtle.importKey(
'raw',
keyData,
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-derivebits-hkdf.js
Expand Up @@ -6,7 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;

function getDeriveKeyInfo(name, length, hash, ...usages) {
return [{ name, length, hash }, usages];
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-derivebits.js
Expand Up @@ -7,7 +7,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;

// This is only a partial test. The WebCrypto Web Platform Tests
// will provide much greater coverage.
Expand Down
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivekey-cfrg.js
Expand Up @@ -6,8 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
const { subtle } = globalThis.crypto;

const kTests = [
{
Expand Down Expand Up @@ -168,7 +167,7 @@ async function prepareKeys() {

{
// Public is a secret key
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
const key = await subtle.importKey(
'raw',
keyData,
Expand Down
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivekey-ecdh.js
Expand Up @@ -6,8 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
const { subtle } = globalThis.crypto;

const kTests = [
{
Expand Down Expand Up @@ -227,7 +226,7 @@ async function prepareKeys() {

{
// Public is a secret key
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
const key = await subtle.importKey(
'raw',
keyData,
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-webcrypto-derivekey.js
Expand Up @@ -7,7 +7,8 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto: { subtle }, KeyObject } = require('crypto');
const { subtle } = globalThis.crypto;
const { KeyObject } = require('crypto');

// This is only a partial test. The WebCrypto Web Platform Tests
// will provide much greater coverage.
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-digest.js
Expand Up @@ -7,7 +7,7 @@ if (!common.hasCrypto)

const assert = require('assert');
const { Buffer } = require('buffer');
const { subtle } = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;
const { createHash } = require('crypto');

const kTests = [
Expand Down
9 changes: 4 additions & 5 deletions test/parallel/test-webcrypto-encrypt-decrypt-aes.js
Expand Up @@ -6,8 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
const { subtle } = globalThis.crypto;

async function testEncrypt({ keyBuffer, algorithm, plaintext, result }) {
// Using a copy of plaintext to prevent tampering of the original
Expand Down Expand Up @@ -214,8 +213,8 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
['encrypt', 'decrypt'],
);

const iv = webcrypto.getRandomValues(new Uint8Array(12));
const aad = webcrypto.getRandomValues(new Uint8Array(32));
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
const aad = globalThis.crypto.getRandomValues(new Uint8Array(32));

const encrypted = await subtle.encrypt(
{
Expand All @@ -225,7 +224,7 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
tagLength: 128
},
secretKey,
webcrypto.getRandomValues(new Uint8Array(32))
globalThis.crypto.getRandomValues(new Uint8Array(32))
);

await subtle.decrypt(
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-encrypt-decrypt-rsa.js
Expand Up @@ -6,7 +6,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const { subtle } = globalThis.crypto;

const {
passing
Expand Down