Skip to content
Open
Show file tree
Hide file tree
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
25 changes: 24 additions & 1 deletion doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -2255,12 +2255,20 @@ be listed in the `transferList` argument.

<!-- YAML
added: v15.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a non-extractable CryptoKey as `key` is deprecated.
-->

* `key` {CryptoKey}
* Returns: {KeyObject}

Example: Converting a `CryptoKey` instance to a `KeyObject`:
Returns the underlying {KeyObject} of a {CryptoKey}. The returned {KeyObject}
does not retain any of the restrictions imposed by the Web Crypto API on the
original {CryptoKey}, such as the allowed key usages, the algorithm or hash
algorithm bindings, and the extractability flag. In particular, the underlying
key material of the returned {KeyObject} can always be exported.

```mjs
const { KeyObject } = await import('node:crypto');
Expand Down Expand Up @@ -3522,6 +3530,9 @@ operations. The specific constants currently defined are described in
<!-- YAML
added: v0.1.94
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
- version:
- v17.9.0
- v16.17.0
Expand Down Expand Up @@ -3596,6 +3607,9 @@ given IV will be.
<!-- YAML
added: v0.1.94
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
- version:
- v17.9.0
- v16.17.0
Expand Down Expand Up @@ -3819,6 +3833,9 @@ input.on('readable', () => {
<!-- YAML
added: v0.1.94
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
- version: v15.0.0
pr-url: https://github.com/nodejs/node/pull/35093
description: The key can also be an ArrayBuffer or CryptoKey. The
Expand Down Expand Up @@ -3909,6 +3926,9 @@ input.on('readable', () => {
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62240
description: Added support for `'raw-private'` and `'raw-seed'`
Expand Down Expand Up @@ -3957,6 +3977,9 @@ of the passphrase is limited to 1024 bytes.
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62240
description: Added support for `'raw-public'` format.
Expand Down
10 changes: 8 additions & 2 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -4485,12 +4485,15 @@ const server = http2.createSecureServer({
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Runtime deprecation.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62321
description: Documentation-only deprecation.
-->
Type: Documentation-only
Type: Runtime
Passing a [`CryptoKey`][] to `node:crypto` functions is deprecated and
will throw an error in a future version. This includes
Expand All @@ -4507,12 +4510,15 @@ will throw an error in a future version. This includes
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Runtime deprecation.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62321
description: Documentation-only deprecation.
-->
Type: Documentation-only
Type: Runtime
Passing a non-extractable [`CryptoKey`][] to [`KeyObject.from()`][] is
deprecated and will throw an error in a future version.
Expand Down
38 changes: 31 additions & 7 deletions lib/internal/crypto/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const {

const {
customInspectSymbol: kInspect,
getDeprecationWarningEmitter,
kEnumerableProperty,
lazyDOMException,
} = require('internal/util');
Expand All @@ -89,6 +90,18 @@ const kKeyUsages = Symbol('kKeyUsages');
const kCachedAlgorithm = Symbol('kCachedAlgorithm');
const kCachedKeyUsages = Symbol('kCachedKeyUsages');

const emitDEP0203 = getDeprecationWarningEmitter(
'DEP0203',
'Passing a CryptoKey to node:crypto functions is deprecated.',
);

const maybeEmitDEP0204 = getDeprecationWarningEmitter(
'DEP0204',
'Passing a non-extractable CryptoKey to KeyObject.from() is deprecated.',
undefined,
false,
(key) => !key[kExtractable],
);

// Key input contexts.
const kConsumePublic = 0;
Expand Down Expand Up @@ -140,6 +153,7 @@ const {
static from(key) {
if (!isCryptoKey(key))
throw new ERR_INVALID_ARG_TYPE('key', 'CryptoKey', key);
maybeEmitDEP0204(key);
return key[kKeyObject];
}

Expand Down Expand Up @@ -796,21 +810,28 @@ function prepareAsymmetricKey(key, ctx) {
if (isKeyObject(key)) {
// Best case: A key object, as simple as that.
return { data: getKeyObjectHandle(key, ctx) };
} else if (isCryptoKey(key)) {
}
if (isCryptoKey(key)) {
emitDEP0203();
return { data: getKeyObjectHandle(key[kKeyObject], ctx) };
} else if (isStringOrBuffer(key)) {
}
if (isStringOrBuffer(key)) {
// Expect PEM by default, mostly for backward compatibility.
return { format: kKeyFormatPEM, data: getArrayBufferOrView(key, 'key') };
} else if (typeof key === 'object') {
}
if (typeof key === 'object') {
const { key: data, encoding, format } = key;

// The 'key' property can be a KeyObject as well to allow specifying
// additional options such as padding along with the key.
if (isKeyObject(data))
if (isKeyObject(data)) {
return { data: getKeyObjectHandle(data, ctx) };
else if (isCryptoKey(data))
}
if (isCryptoKey(data)) {
emitDEP0203();
return { data: getKeyObjectHandle(data[kKeyObject], ctx) };
else if (format === 'jwk') {
}
if (format === 'jwk') {
validateObject(data, 'key.key');
return { data: getKeyObjectHandleFromJwk(data, ctx), format: 'jwk' };
} else if (format === 'raw-public' || format === 'raw-private' ||
Expand All @@ -836,6 +857,7 @@ function prepareAsymmetricKey(key, ctx) {
...parseKeyEncoding(key, undefined, isPublic),
};
}

throw new ERR_INVALID_ARG_TYPE(
'key',
getKeyTypes(ctx !== kCreatePrivate),
Expand All @@ -856,7 +878,9 @@ function prepareSecretKey(key, encoding, bufferOnly = false) {
if (key.type !== 'secret')
throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, 'secret');
return key[kHandle];
} else if (isCryptoKey(key)) {
}
if (isCryptoKey(key)) {
emitDEP0203();
if (key[kKeyType] !== 'secret')
throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key[kKeyType], 'secret');
return key[kKeyObject][kHandle];
Expand Down
23 changes: 23 additions & 0 deletions test/parallel/test-crypto-dep0203.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');

const crypto = require('crypto');

common.expectWarning({
DeprecationWarning: {
DEP0203: 'Passing a CryptoKey to node:crypto functions is deprecated.',
},
});

(async () => {
const key = await globalThis.crypto.subtle.generateKey(
{ name: 'AES-CBC', length: 128 },
true,
['encrypt'],
);

crypto.createCipheriv('aes-128-cbc', key, Buffer.alloc(16));
})().then(common.mustCall());
23 changes: 23 additions & 0 deletions test/parallel/test-crypto-dep0204.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');

const { KeyObject } = require('crypto');

common.expectWarning({
DeprecationWarning: {
DEP0204: 'Passing a non-extractable CryptoKey to KeyObject.from() is deprecated.',
},
});

(async () => {
const key = await globalThis.crypto.subtle.generateKey(
{ name: 'AES-CBC', length: 128 },
false, // non-extractable
['encrypt'],
);

KeyObject.from(key);
})().then(common.mustCall());
Loading