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
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -239,6 +239,12 @@ module.exports = {
selector: "CallExpression[callee.name='isNaN']",
message: 'Use Number.isNaN() instead of the global isNaN() function.',
},
{
// 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',
9 changes: 3 additions & 6 deletions benchmark/crypto/webcrypto-digest.js
Original file line number Diff line number Diff line change
@@ -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'],
@@ -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);
12 changes: 4 additions & 8 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
@@ -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',
@@ -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({
4 changes: 2 additions & 2 deletions src/crypto/README.md
Original file line number Diff line number Diff line change
@@ -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) => {
2 changes: 2 additions & 0 deletions test/.eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions test/parallel/test-crypto-psychic-signatures.js
Original file line number Diff line number Diff line change
@@ -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,
3 changes: 1 addition & 2 deletions test/parallel/test-crypto-random.js
Original file line number Diff line number Diff line change
@@ -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;
@@ -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);
});
8 changes: 4 additions & 4 deletions test/parallel/test-crypto-subtle-zero-length.js
Original file line number Diff line number Diff line change
@@ -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));
@@ -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);
Original file line number Diff line number Diff line change
@@ -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),
{
@@ -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));
3 changes: 2 additions & 1 deletion test/parallel/test-global-webcrypto-classes.js
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ if (!common.hasCrypto)
common.skip('missing crypto');

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

// Test CryptoKey constructor
{
@@ -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()),
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-cryptokey-workers.js
Original file line number Diff line number Diff line change
@@ -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 {
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivebits-cfrg.js
Original file line number Diff line number Diff line change
@@ -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 = [
{
@@ -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,
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivebits-ecdh.js
Original file line number Diff line number Diff line change
@@ -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 = [
{
@@ -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,
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-derivebits-hkdf.js
Original file line number Diff line number Diff line change
@@ -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];
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-derivebits.js
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivekey-cfrg.js
Original file line number Diff line number Diff line change
@@ -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 = [
{
@@ -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,
5 changes: 2 additions & 3 deletions test/parallel/test-webcrypto-derivekey-ecdh.js
Original file line number Diff line number Diff line change
@@ -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 = [
{
@@ -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,
3 changes: 2 additions & 1 deletion test/parallel/test-webcrypto-derivekey.js
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-digest.js
Original file line number Diff line number Diff line change
@@ -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 = [
9 changes: 4 additions & 5 deletions test/parallel/test-webcrypto-encrypt-decrypt-aes.js
Original file line number Diff line number Diff line change
@@ -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
@@ -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(
{
@@ -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(
2 changes: 1 addition & 1 deletion test/parallel/test-webcrypto-encrypt-decrypt-rsa.js
Original file line number Diff line number Diff line change
@@ -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
Loading