From 011910b424111dec4dcd6915624d55c14ab89edd Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 26 Jan 2021 18:21:14 +0100 Subject: [PATCH] crypto: add keyObject.export() 'jwk' format option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds [JWK](https://tools.ietf.org/html/rfc7517) keyObject.export format option. Supported key types: `ec`, `rsa`, `ed25519`, `ed448`, `x25519`, `x448`, and symmetric keys, resulting in JWK `kty` (Key Type) values `EC`, `RSA`, `OKP`, and `oct`. `rsa-pss` is not supported since the JWK format does not support PSS Parameters. `EC` JWK curves supported are `P-256`, `secp256k1`, `P-384`, and `P-521` PR-URL: https://github.com/nodejs/node/pull/37081 Reviewed-By: James M Snell Reviewed-By: Tobias Nießen --- doc/api/crypto.md | 25 +- doc/api/errors.md | 14 ++ lib/internal/crypto/keys.js | 60 ++++- lib/internal/errors.js | 2 + test/fixtures/keys/Makefile | 42 +++- test/fixtures/keys/ec_p256_private.pem | 5 + test/fixtures/keys/ec_p256_public.pem | 4 + test/fixtures/keys/ec_p384_private.pem | 6 + test/fixtures/keys/ec_p384_public.pem | 5 + test/fixtures/keys/ec_p521_private.pem | 8 + test/fixtures/keys/ec_p521_public.pem | 6 + test/fixtures/keys/ec_secp256k1_private.pem | 5 + test/fixtures/keys/ec_secp256k1_public.pem | 4 + test/parallel/test-crypto-key-objects.js | 241 +++++++++++++++++++- 14 files changed, 402 insertions(+), 25 deletions(-) create mode 100644 test/fixtures/keys/ec_p256_private.pem create mode 100644 test/fixtures/keys/ec_p256_public.pem create mode 100644 test/fixtures/keys/ec_p384_private.pem create mode 100644 test/fixtures/keys/ec_p384_public.pem create mode 100644 test/fixtures/keys/ec_p521_private.pem create mode 100644 test/fixtures/keys/ec_p521_public.pem create mode 100644 test/fixtures/keys/ec_secp256k1_private.pem create mode 100644 test/fixtures/keys/ec_secp256k1_public.pem diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 8de7ed38677a97..9088b78babdadb 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1348,35 +1348,41 @@ keys. ### `keyObject.export([options])` * `options`: {Object} -* Returns: {string | Buffer} +* Returns: {string | Buffer | Object} -For symmetric keys, this function allocates a `Buffer` containing the key -material and ignores any options. +For symmetric keys, the following encoding options can be used: -For asymmetric keys, the `options` parameter is used to determine the export -format. +* `format`: {string} Must be `'buffer'` (default) or `'jwk'`. For public keys, the following encoding options can be used: * `type`: {string} Must be one of `'pkcs1'` (RSA only) or `'spki'`. -* `format`: {string} Must be `'pem'` or `'der'`. +* `format`: {string} Must be `'pem'`, `'der'`, or `'jwk'`. For private keys, the following encoding options can be used: * `type`: {string} Must be one of `'pkcs1'` (RSA only), `'pkcs8'` or `'sec1'` (EC only). -* `format`: {string} Must be `'pem'` or `'der'`. +* `format`: {string} Must be `'pem'`, `'der'`, or `'jwk'`. * `cipher`: {string} If specified, the private key will be encrypted with the given `cipher` and `passphrase` using PKCS#5 v2.0 password based encryption. * `passphrase`: {string | Buffer} The passphrase to use for encryption, see `cipher`. -When PEM encoding was selected, the result will be a string, otherwise it will -be a buffer containing the data encoded as DER. +The result type depends on the selected encoding format, when PEM the +result is a string, when DER it will be a buffer containing the data +encoded as DER, when [JWK][] it will be an object. + +When [JWK][] encoding format was selected, all other encoding options are +ignored. PKCS#1, SEC1, and PKCS#8 type keys can be encrypted by using a combination of the `cipher` and `format` options. The PKCS#8 `type` can be used with any @@ -4355,6 +4361,7 @@ See the [list of SSL OP Flags][] for details. [Crypto constants]: #crypto_crypto_constants_1 [HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed [HTML5's `keygen` element]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen +[JWK]: https://tools.ietf.org/html/rfc7517 [NIST SP 800-131A]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf [NIST SP 800-132]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf diff --git a/doc/api/errors.md b/doc/api/errors.md index 896a403188cbc2..411e2a4221004e 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -919,6 +919,18 @@ added: v15.0.0 Initialization of an asynchronous crypto operation failed. + +### `ERR_CRYPTO_JWK_UNSUPPORTED_CURVE` + +Key's Elliptic Curve is not registered for use in the +[JSON Web Key Elliptic Curve Registry][]. + + +### `ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE` + +Key's Asymmetric Key Type is not registered for use in the +[JSON Web Key Types Registry][]. + ### `ERR_CRYPTO_OPERATION_FAILED`