profile
viewpoint
James M Snell jasnell @nearform Clovis, California http://jasnell.me "I can't breathe" #bidenharris202 #blacklivesmatter #notmypresident

jasnell/activitystrea.ms 140

Activity Streams 2.0 for Node.js (this package is not actively maintained, if you'd like to help, let me know)

Fishrock123/bob 68

🚰 binary data "streams+" via data producers, data consumers, and pull flow.

davidmarkclements/proffer 11

Realtime V8 Tick Profiler

jasnell/activitystreams 5

Activity Streams 2.0 Java Reference Implementation

jasnell/activitystreams.jsonld 5

http://asjsonld.mybluemix.net

addaleax/node 4

Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:

jasnell/as2-schema 4

activitystrea.ms schema.org extensions

push eventjasnell/node

James M Snell

commit sha 31dfbd500e6242b8cd4aa0fd4b19d955eb37a4a1

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 14 hours

PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha 6ee370370b7b5ac4d5a5d8980b26f9b47d5301f9

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 17 hours

push eventjasnell/node

James M Snell

commit sha 9b614fe70f4b0329644a00c371a9d705c2ab0b4e

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 17 hours

push eventjasnell/node

James M Snell

commit sha 643143c61516ccecf7fdbf769e6fd09fe02c8179

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 18 hours

push eventjasnell/node

James M Snell

commit sha 208c41e484eb573620bc13be88d5b548433e0dee

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 20 hours

issue commentnodejs/node

npm run fails on Windows10 with WSL2

I agree. This is not a Node.js issue. The npm client is the one that manages the .bin directory and attempts to invoke those. I recommend opening an issue with npm instead and agree that this is a wontfix.

wgorski

comment created time in 2 days

issue commentnodejs/node

workers, crypto: passing KeyObject as workerData crashes

I was going to work up the fix this next week as part of #35093 but if someone wants to pick it up, feel free!

jasnell

comment created time in 2 days

push eventjasnell/node

James M Snell

commit sha cd67a0d476a4f47c2274192c1aa60e7ad1c67ebb

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha 41928639df3656fb1b0e384feaa40ac37bc43eb9

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 4 days

issue openednodejs/node

workers: insufficient detail when cloneable deserialization fails

Suppose we have an internal object that we want to make cloneable to a Worker..

class MyObject extends JSTransferable {
  constructor() {}

  [kClone]() {
    return {
      data: {},
      deserializeInfo: 'internal/whatever'
    };
  }

  [kDeserialize]({}) {}
}

If the deserializeInfo property is missing or incorrect, the deserialization of the object fails silently with no information about the failure given.

created time in 4 days

issue commentnodejs/node

workers, crypto: passing KeyObject as workerData crashes

Ok... yeah, it's what I suspected... KeyObjectHandle::Create() depends on env->crypto_key_object_handle_constructor() being set, which it is not until internalBinding('crypto') is called... so when the attempt is made to deserialize the KeyObject in the Worker, we get a crash.

jasnell

comment created time in 4 days

issue openednodejs/node

workers, crypto: passing KeyObject as workerData crashes

@addaleax ... The following segfaults on master and 14.x ...

I'll be investigating shortly...

'use strict';

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

const { Worker, isMainThread, workerData } = require('worker_threads');

if (isMainThread) {
  const key = createSecretKey(Buffer.from('hello'));
  new Worker(__filename, { workerData: key });
} else {
  console.log(workerData);
}

lldb yields...

james@ubuntu:~/node/node$ lldb -- node ../tmp/test
(lldb) target create "node"
Current executable set to 'node' (x86_64).
(lldb) settings set -- target.run-args  "../tmp/test"
(lldb) r
Process 20852 launched: '/home/james/node/node/node' (x86_64)
Process 20852 stopped
* thread #2, name = 'node', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x00005555560fb837 node`v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) + 103
node`v8::internal::(anonymous namespace)::Invoke:
->  0x5555560fb837 <+103>: movq   (%r13), %rax
    0x5555560fb83b <+107>: testb  $0x1, %al
    0x5555560fb83d <+109>: jne    0x5555560fba10            ; <+576>
    0x5555560fb843 <+115>: movl   0x3320(%rbx), %r13d
(lldb) bt
* thread #2, name = 'node', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
  * frame #0: 0x00005555560fb837 node`v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) + 103
    frame #1: 0x00005555560fcb7d node`v8::internal::Execution::New(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) + 109
    frame #2: 0x0000555555f8f01f node`v8::Function::NewInstanceWithSideEffectType(v8::Local<v8::Context>, int, v8::Local<v8::Value>*, v8::SideEffectType) const + 415
    frame #3: 0x0000555555ee51d8 node`node::crypto::KeyObjectHandle::Create(node::Environment*, std::shared_ptr<node::crypto::KeyObjectData>) + 40
    frame #4: 0x0000555555ee6f91 node`node::crypto::NativeKeyObject::KeyObjectTransferData::Deserialize(node::Environment*, v8::Local<v8::Context>, std::unique_ptr<node::worker::TransferData, std::default_delete<node::worker::TransferData> >) + 385
    frame #5: 0x0000555555d73130 node`node::worker::Message::Deserialize(node::Environment*, v8::Local<v8::Context>) + 464
    frame #6: 0x0000555555d78335 node`node::worker::MessagePort::ReceiveMessage(v8::Local<v8::Context>, bool) + 1605
    frame #7: 0x0000555555d788b8 node`node::worker::MessagePort::OnMessage() + 312
    frame #8: 0x000055555686c8c6 node`uv__async_io(loop=0x00007ffff447ba48, w=<unavailable>, events=<unavailable>) at async.c:163
    frame #9: 0x0000555556880f84 node`uv__io_poll(loop=0x00007ffff447ba48, timeout=<unavailable>) at linux-core.c:461
    frame #10: 0x000055555686d1fa node`uv_run(loop=0x00007ffff447ba48, mode=UV_RUN_DEFAULT) at core.c:385
    frame #11: 0x0000555555e00336 node`node::worker::Worker::Run() + 5766
    frame #12: 0x0000555555e00707 node`node::worker::Worker::StartThread(v8::FunctionCallbackInfo<v8::Value> const&)::'lambda'(void*)::_FUN(void*) + 71
    frame #13: 0x00007ffff707a6db libpthread.so.0`start_thread + 219
    frame #14: 0x00007ffff6da3a3f libc.so.6`__GI___clone at clone.S:95
(lldb)

created time in 4 days

push eventjasnell/node

James M Snell

commit sha 35631fccb97c6022f4095de4f38e664cdb075b71

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 4 days

push eventjasnell/node

James M Snell

commit sha 96d4323c35c180a1c40620c00595d9ca4498cae6

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 4 days

push eventjasnell/node

James M Snell

commit sha 07bb2c27233f99d51f14273f18901fff9df3a5a0

fixup! crypto: refactoring internals, add WebCrypto

view details

push time in 4 days

push eventjasnell/node

James M Snell

commit sha 3fd9ff38192dd0b171232f55a07a052634960da3

crypto: move node_crypto files to src/crypto Signed-off-by: James M Snell <jasnell@gmail.com>

view details

James M Snell

commit sha feea78f546134b21b814a93c5ab9ab0e27eb27b2

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 4 days

issue closednodejs/node

[discuss] event loop idle metrics

@trevnorris is working on landing a change to libuv that will track and report the amount of time the event loop spends in idle time. It's an extremely useful metric that can provide for us a measurement of "event loop utilization". In a world of worker threads, monitoring CPU no longer becomes an effective way of monitoring performance and event loop delay is not enough on it's own, so having a built in mechanism for measuring event loop utilization would be fantastic. While there is some work still to be done to get the PR landed in libuv and get that new libuv version landed in core, I did want to briefly discuss how the new metric should be exposed in core.

In this comment @trevnorris suggests a simple performance.idleTime() that returns the direct value of this metric, which records the cumulative time spent in idle since the loop was configured to track. To calculate event loop utilization, however, we also need to know how long the event loop has been running (well, to be specific, how long it's been since the loop was configured to collect the data, which can be turned on but not turned off). Assuming we started the loop and started collecting the metric from the start, we do already record the start time of the event loop (using the performance milestones) so someone could calculate the utilization on their own by accessing those values. However, I think it might make more sense for us to just do the calculation for users and provide an API like performance.idleTime() that returns an object with two values { idle: n, utilization: y } where idle is the raw idle time and utilization is the calculated utilization value. The API should be very low cost to sample using AliasedArray or AliasedStruct as a backing.

/cc @nodejs/diagnostics @addaleax @mcollina

closed time in 4 days

jasnell

push eventjasnell/node

Michael Dawson

commit sha fe293e914c3b9a65d2024971ebbefcf8a93dc549

doc: add technical values document As part of the [next-10](https://github.com/nodejs/next-10) we found we needed to capture the project's technical values/priorities as a starting point before discussing key technologies/areas for the next 10 years of Node.js This is a first cut that the team put together. The discussion took place in a few meetings as well as this [PR](https://github.com/nodejs/next-10/pull/11). We believe the doc should live in the core node repository as it is intended to reflect the agreement of the collaborator base. I think this is a good starting point but we also acknowledge that only a small subset of the Node.js collaborators have participated/commented so far. This PR should be a good way to get additional review/input from the larger set of Node.js collaborators. Signed-off-by: Michael Dawson <mdawson@devrus.com> PR-URL: https://github.com/nodejs/node/pull/35145 Reviewed-By: Christopher Hiller <boneskull@boneskull.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Ruy Adorno <ruyadorno@github.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ash Cripps <acripps@redhat.com> Reviewed-By: Ben Coe <bencoe@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Pranshu Srivastava <rexagod@gmail.com>

view details

Phillip Johnsen

commit sha c24ad832bbc6476eeb90deafdebb758ecd68d0de

build: increase API requests for stale action The second attempt at getting the auto closing of issues & PRs to work as expected without hitting a maximum operations allowed error we've been seeing. Recently discovered that the mentioned error is actually self imposed by the stale action itself. It keeps track of how many outgoing GitHub API requests it performs, and if that count exceeds the configured `operations-per-run` option, it exits to avoid hitting API rate limits. Default `operations-per-run` value is set to `30`. That's a very low limit and we're not at all concerned hitting that rate limit as of now, so we're bumping `operations-per-run` to `500` with these changes. Refs https://github.com/nodejs/node/issues/35144 PR-URL: https://github.com/nodejs/node/pull/35235 Reviewed-By: Mary Marchini <oss@mmarchini.me> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

cjihrig

commit sha c314c04079bbf93d786a5855d0eaaed30d36820e

test: add wasi readdir() test This commit provides coverage for __wasi_fd_readdir(). PR-URL: https://github.com/nodejs/node/pull/35202 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jiawen Geng <technicalcute@gmail.com>

view details

Turner Jabbour

commit sha 59ca56eddefc78bab87d7e8e074b3af843ab1bc3

doc: fix small grammatical issues in timers.md PR-URL: https://github.com/nodejs/node/pull/35203 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Gerhard Stoebich

commit sha c9506a8f3e9bc5c679151feb39198023154464ab

n-api: add more property defaults Add a default value for class method and js like property in enum napi_property_attributes. n-api currently offers only one default which is non configurable, non writable, non enumerable - like Object.defineProperty(). While this is formal correct the usual way to create properties in JS is either by defining a class or use obj.prop = value. The defaults from these variants are now backed into enum values. PR-URL: https://github.com/nodejs/node/pull/35214 Refs: https://github.com/nodejs/node-addon-api/issues/811 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>

view details

Guy Bedford

commit sha 2d868fe822af00c65c9487546e0f313ef3d04564

module: exports pattern support PR-URL: https://github.com/nodejs/node/pull/34718 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>

view details

Rich Trott

commit sha 018a6a4ab13247958a2db3203e15e4338f87c6dc

doc: fix header level for error code PR-URL: https://github.com/nodejs/node/pull/35219 Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha 14e98825a1e35f17b03aab22db52bc81e3a3ec94

doc: alphabetize error list PR-URL: https://github.com/nodejs/node/pull/35219 Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Michaël Zasso

commit sha ed8af4e93831d3cf21d5562e900371d796b5fa20

doc: add issue labels sections to release guide PR-URL: https://github.com/nodejs/node/pull/35224 Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

James M Snell

commit sha 0dbdd2921a44f01bbd4efa4bb8f484ccb35d9d5e

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 4 days

push eventjasnell/node

push time in 4 days

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 using v8::Value; namespace crypto { namespace Timing { +struct BigIntInfo {+  int sign_bit;+  int word_count;+  std::unique_ptr<uint64_t> words;+};++void TimingSafeEqualBigInt(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  if (!args[0]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val1\" argument must be a bigint.");+    return;+  }+  if (!args[1]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val2\" argument must be a bigint.");+    return;+  }++  BigIntInfo inf1 {};+  BigIntInfo inf2 {};++  Local<v8::BigInt> b1 = args[0].As<v8::BigInt>();+  Local<v8::BigInt> b2 = args[1].As<v8::BigInt>();++  inf1.word_count = b1->WordCount();+  inf2.word_count = b2->WordCount();++  if (inf1.word_count != inf2.word_count)+    return args.GetReturnValue().Set(false);++  inf1.words.reset(Malloc<uint64_t>(inf1.word_count));+  inf2.words.reset(Malloc<uint64_t>(inf1.word_count));++  b1->ToWordsArray(&inf1.sign_bit, &inf1.word_count, inf1.words.get());+  b2->ToWordsArray(&inf2.sign_bit, &inf2.word_count, inf2.words.get());

Tell you what, I don't want this PR to be held up on this particular point so I'm going to remove this commit and push it to a separate PR after we get the rest of the changes here resolved

jasnell

comment created time in 4 days

PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha 1e79dbf827654d5813d97bddc9fb9819b0075aff

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

James M Snell

commit sha 8ed1601508f6140ff77bb375e1fe51eb3eadfef6

crypto: add timingSafeEqual.bigint Variation on timingSafeEqual that uses a constant time algorithm to compare bigints.

view details

push time in 4 days

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 using v8::Value; namespace crypto { namespace Timing { +struct BigIntInfo {+  int sign_bit;+  int word_count;+  std::unique_ptr<uint64_t> words;+};++void TimingSafeEqualBigInt(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  if (!args[0]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val1\" argument must be a bigint.");+    return;+  }+  if (!args[1]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val2\" argument must be a bigint.");+    return;+  }++  BigIntInfo inf1 {};+  BigIntInfo inf2 {};++  Local<v8::BigInt> b1 = args[0].As<v8::BigInt>();+  Local<v8::BigInt> b2 = args[1].As<v8::BigInt>();++  inf1.word_count = b1->WordCount();+  inf2.word_count = b2->WordCount();++  if (inf1.word_count != inf2.word_count)+    return args.GetReturnValue().Set(false);++  inf1.words.reset(Malloc<uint64_t>(inf1.word_count));+  inf2.words.reset(Malloc<uint64_t>(inf1.word_count));++  b1->ToWordsArray(&inf1.sign_bit, &inf1.word_count, inf1.words.get());+  b2->ToWordsArray(&inf2.sign_bit, &inf2.word_count, inf2.words.get());

It just passes along whatever is stored in the internal representation – I know that because I wrote it. ;)

Heh... yeah I figured you may have. I was speaking more about the contract of the call and not necessarily how it's implemented internally, but we definitely should get clarity on this. Btw, this kind of thing is exactly why this is in a separate commit ;-)

jasnell

comment created time in 4 days

PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha d4294933e3167b83420886f2ddd018af40be77e9

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

James M Snell

commit sha e9000ae677dd02cd21960703421b41459b62bccc

crypto: add timingSafeEqual.bigint Variation on timingSafeEqual that uses a constant time algorithm to compare bigints.

view details

push time in 4 days

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 using v8::Value; namespace crypto { namespace Timing { +struct BigIntInfo {+  int sign_bit;+  int word_count;+  std::unique_ptr<uint64_t> words;+};++void TimingSafeEqualBigInt(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  if (!args[0]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val1\" argument must be a bigint.");+    return;+  }+  if (!args[1]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val2\" argument must be a bigint.");+    return;+  }++  BigIntInfo inf1 {};+  BigIntInfo inf2 {};++  Local<v8::BigInt> b1 = args[0].As<v8::BigInt>();+  Local<v8::BigInt> b2 = args[1].As<v8::BigInt>();++  inf1.word_count = b1->WordCount();+  inf2.word_count = b2->WordCount();++  if (inf1.word_count != inf2.word_count)+    return args.GetReturnValue().Set(false);++  inf1.words.reset(Malloc<uint64_t>(inf1.word_count));+  inf2.words.reset(Malloc<uint64_t>(inf1.word_count));++  b1->ToWordsArray(&inf1.sign_bit, &inf1.word_count, inf1.words.get());+  b2->ToWordsArray(&inf2.sign_bit, &inf2.word_count, inf2.words.get());

Let's see if we can get clarification from @nodejs/v8, however, I still think we're fine. Regardless of what V8 chooses to do internally, BigInt::WordCount() should still return the minimal number of words necessary to encode the value and a quick test shows that it does.

jasnell

comment created time in 4 days

PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha c81dd200599a24b17ed8bd08ef2cf44717a75228

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

James M Snell

commit sha 5debc854640205fedd9418a796c62a3cb4f5d315

crypto: add timingSafeEqual.bigint Variation on timingSafeEqual that uses a constant time algorithm to compare bigints.

view details

push time in 4 days

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 crypto.randomFill(buf, 5, 5, (err, buf) => { }); ``` -Any `TypedArray` or `DataView` instance may be passed as `buffer`.+Any `ArrayBuffer` `TypedArray` or `DataView` instance may be passed as

Note also that nearly all of the WebCrypto API promises that do not resolve as CryptoKey or boolean resolve as ArrayBuffer.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv, #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD  // BINARY is a deprecated alias of LATIN1.-enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER, LATIN1 = BINARY};+// BASE64URL is not currently exposed to the JavaScript side.+enum encoding {+  ASCII,+  UTF8,+  BASE64,+  BASE64URL,

Yeah.. unfortunately because that's a bit messy because of the LATIN1 = BINARY ... I'm not 100% clear, is the following ABI breaking also or do we have to put BASE64URL after LATIN1?

// Can we do this without breaking ABI...
enum encoding {
  ASCII,
  UTF8,
  BASE64,
  UCS2,
  BINARY,
  HEX,
  BUFFER,
  BASE64URL,
  LATIN1 = BINARY,
};
// Or does it have to be this
enum encoding {
  ASCII,
  UTF8,
  BASE64,
  UCS2,
  BINARY,
  HEX,
  BUFFER,
  LATIN1 = BINARY,
  // Because LATIN1 is set explicitly to equal BINARY, we
  // have to explicitly set BASE64URL to a value to continue
  // on, otherwise it will be set to BINARY + 1...
  BASE64URL = 7
};
jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

+# WebCrypto API++<!-- introduced_in=REPLACEME -->++> Stability: 0 - Experimental++<!-- source_link=lib/crypto/promises.js -->++The `crypto/promises` module provides an implementation of the standard+[WebCrypto API][].++Use `require('crypto/promises')` to access this module.++```js+const { subtle } = require('crypto/promises');++(async function() {++  const key = await subtle.generateKey({+    name: 'hmac',+    length: 123+  }, true, ['sign', 'verify']);++  const digest = await subtle.sign({+    name: 'hmac'+  }, key, 'I love cupcakes');++})();+```++## Determining if WebCrypto API support is unavailable++It is possible for Node.js to be built without including support for the+`crypto/promises` module. In such cases, calling `require('crypto/promises')`+will result in an error being thrown.++```js+let crypto;+try {+  crypto = require('crypto/promises');+} catch (err) {+  console.log('crypto support is disabled!');+}+```++## Examples++### Generating keys++The {SubtleCrypto} class can be used to generate symmetric (secret) keys+or asymmetric key pairs (public key and private key).++#### AES keys++```js+const { subtle } = require('crypto/promises');++async function generateAesKey(length = 256) {+  const key = await subtle.generateKey({+    name: 'AES-CBC',+    length+  }, true, ['encrypt', 'decrypt']);++  return key;+}+```++#### Elliptic curve key pairs++```js+const { subtle } = require('crypto/promises');++async function generateEcKey(namedCurve = 'P-521') {+  const {+    publicKey,+    privateKey+  } = await subtle.generateKey({+    name: 'ECDSA',+    namedCurve,+  }, true, ['sign', 'verify']);++  return { publicKey, privateKey };+}+```++#### HMAC keys++```js+const { subtle } = require('crypto/promises');++async function generateAesKey(hash = 'SHA-256') {+  const key = await subtle.generateKey({+    name: 'HMAC',+    hash+  }, true, ['sign', 'verify']);++  return key;+}+```++#### RSA key pairs++```js+const { subtle } = require('crypto/promises');+const publicExponent = new Uint8Array([1, 0, 1]);++async function generateRsaKey(modulusLength = 2048, hash = 'SHA-256') {+  const {+    publicKey,+    privateKey+  } = await subtle.generateKey({+    name: 'RSASSA-PKCS1-v1_5',+    modulusLength,+    publicExponent,+    hash,+  }, true, ['encrypt', 'decrypt']);++  return { publicKey, privateKey };+}+```++### Encryption and decryption++```js+const { subtle, getRandomValues } = require('crypto/promises');++async function aesEncrypt(plaintext) {+  const ec = new TextEncoder();+  const key = await generateAesKey();+  const iv = getRandomValues(new Uint8Array(16));++  const ciphertext = await subtle.encrypt({+    name: 'AES-CBC',+    iv,+  }, key, ec.encode(plaintext));++  return {+    key,+    iv,+    ciphertext+  };+}++async function aesDecrypt(ciphertext, key, iv) {+  const dec = new TextDecoder();+  const plaintext = await subtle.decrypt({+    name: 'AES-CBC',+    iv,+  }, key, ciphertext);++  return dec.decode(plaintext);+}+```++### Exporting and importing keys++```js+const { subtle } = require('crypto/promises');++async function generateAndExportHmacKey(format = 'jwk', hash = 'SHA-512') {+  const key = await subtle.generateKey({+    name: 'HMAC',+    hash+  }, true, ['sign', 'verify']);++  return subtle.exportKey(format, key);+}++async function importHmacKey(keyData, format = 'jwk', hash = 'SHA-512') {+  const key = await subtle.importKey(format, keyData, {+    name: 'HMAC',+    hash+  }, true, ['sign', 'verify']);++  return key;+}+```++### Wrapping and unwrapping keys++```js+const { subtle } = require('crypto/promises');++async function generateAndWrapHmacKey(format = 'jwk', hash = 'SHA-512') {+  const [+    key,+    wrappingKey+  ] = await Promise.all([+    subtle.generateKey({+      name: 'HMAC', hash+    }, true, ['sign', 'verify']),+    subtle.generateKey({+      name: 'AES-KW',+      length: 256+    }, true, ['wrapKey', 'unwrapKey'])+  ]);++  const wrappedKey = await subtle.wrapKey(format, key, wrappingKey, 'AES-KW');++  return wrappedKey;+}++async function unwrapHmacKey(+  wrappedKey,+  wrappingKey,+  format = 'jwk',+  hash = 'SHA-512') {++  const key = await subtle.unwrapKey(+    format,+    wrappedKey,+    unwrappingKey,+    'AES-KW',+    { name: 'HMAC', hash },+    true,+    ['sign', 'verify']);++  return key;+}+```++### Sign and verify++```js+const { subtle } = require('crypto/promises');++async function sign(key, data) {+  const ec = new TextEncoder();+  const signature =+    await subtle.sign('RSASSA-PKCS1-v1_5', key, ec.encode(data));+  return signature;+}++async function verify(key, signature, data) {+  const ec = new TextEncoder();+  const verified =+    await subtle.verify(+      'RSASSA-PKCS1-v1_5',+      key,+      signature,+      ec.encode(data));+  return verified;+}+```++### Deriving bits and keys++```js+const { subtle } = require('crypto/promises');++async function pbkdf2(pass, salt, iterations = 1000, length = 256) {+  const ec = new TextEncoder();+  const key = await subtle.importKey(+    'raw',+    ec.encode(pass),+    'PBKDF2',+    false,+    ['deriveBits']);+  const bits = await subtle.deriveBits({+    name: 'PBKDF2',+    hash: 'SHA-512',+    salt: ec.encode(salt),+    iterations+  }, key, length);+  return bits;+}++async function pbkdf2Key(pass, salt, iterations = 1000, length = 256) {+  const ec = new TextEncoder();+  const keyMaterial = await subtle.importKey(+    'raw',+    ec.encode(pass),+    'PBKDF2',+    false,+    ['deriveBits']);+  const key = await subtle.deriveKey({+    name: 'PBKDF2',+    hash: 'SHA-512',+    salt: ec.encode(salt),+    iterations+  }, keyMaterial, {+    name: 'AES-GCM',+    length: 256+  }, true, ['encrypt', 'decrypt']);+  return key;+}+```++### Digest++```js+const { subtle } = require('crypto/promises');++async function digest(data, algorithm = 'SHA-512') {+  const ec = new TextEncoder();+  const digest = await subtle.digest(algorithm, ec.encode(data));+  return digest;+}+```++## Class: `Crypto`

I'll be going through and adding all of the necessary YAML metadata throughout the document soon.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 constexpr size_t kFsStatsBufferLength =   V(isclosing_string, "isClosing")                                             \   V(issuer_string, "issuer")                                                   \   V(issuercert_string, "issuerCertificate")                                    \+  V(jwk_d_string, "d")                                                         \+  V(jwk_dp_string, "dp")                                                       \+  V(jwk_dq_string, "dq")                                                       \+  V(jwk_dsa_string, "DSA")                                                     \+  V(jwk_e_string, "e")                                                         \+  V(jwk_ec_string, "EC")                                                       \+  V(jwk_g_string, "g")                                                         \+  V(jwk_k_string, "k")                                                         \+  V(jwk_p_string, "p")                                                         \+  V(jwk_q_string, "q")                                                         \+  V(jwk_qi_string, "qi")                                                       \+  V(jwk_kty_string, "kty")                                                     \+  V(jwk_n_string, "n")                                                         \+  V(jwk_oct_string, "oct")                                                     \+  V(jwk_rsa_string, "RSA")                                                     \+  V(jwk_x_string, "x")                                                         \+  V(jwk_y_string, "y")                                                         \

FWIW, longer term, I'd prefer to move these very specific strings out of the Environment and into the module-specific state binding.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 constexpr size_t kFsStatsBufferLength =   V(isclosing_string, "isClosing")                                             \   V(issuer_string, "issuer")                                                   \   V(issuercert_string, "issuerCertificate")                                    \+  V(jwk_d_string, "d")                                                         \+  V(jwk_dp_string, "dp")                                                       \+  V(jwk_dq_string, "dq")                                                       \+  V(jwk_dsa_string, "DSA")                                                     \+  V(jwk_e_string, "e")                                                         \+  V(jwk_ec_string, "EC")                                                       \+  V(jwk_g_string, "g")                                                         \+  V(jwk_k_string, "k")                                                         \+  V(jwk_p_string, "p")                                                         \+  V(jwk_q_string, "q")                                                         \+  V(jwk_qi_string, "qi")                                                       \+  V(jwk_kty_string, "kty")                                                     \+  V(jwk_n_string, "n")                                                         \+  V(jwk_oct_string, "oct")                                                     \+  V(jwk_rsa_string, "RSA")                                                     \+  V(jwk_x_string, "x")                                                         \+  V(jwk_y_string, "y")                                                         \

Well... yes and no... there are plenty of examples in that list like crypto_*_string(), dns_*_string() that don't follow that pattern, and having the prefix makes it much easier to understand the intended context. I'd prefer to keep the prefixes.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

+#ifndef SRC_CRYPTO_CRYPTO_UTIL_H_+#define SRC_CRYPTO_CRYPTO_UTIL_H_++#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS++#include "env.h"+#include "async_wrap.h"+#include "allocated_buffer.h"+#include "node_errors.h"+#include "node_internals.h"+#include "util.h"+#include "v8.h"+#include "string_bytes.h"++#include <openssl/err.h>+#include <openssl/evp.h>+#include <openssl/ec.h>+#include <openssl/kdf.h>+#include <openssl/rsa.h>+#include <openssl/dsa.h>+#include <openssl/ssl.h>+#ifndef OPENSSL_NO_ENGINE+#  include <openssl/engine.h>+#endif  // !OPENSSL_NO_ENGINE++#include <memory>+#include <string>+#include <vector>+#include <climits>+#include <cstdio>++namespace node {+namespace crypto {++// Currently known sizes of commonly used OpenSSL struct sizes.+// OpenSSL considers it's various structs to be opaque and the+// sizes may change from one version of OpenSSL to another, so+// these values should not be trusted to remain static. These+// are provided to allow for some close to reasonable memory+// tracking.+constexpr size_t kSizeOf_DH = 144;+constexpr size_t kSizeOf_EC_KEY = 80;+constexpr size_t kSizeOf_EVP_CIPHER_CTX = 168;+constexpr size_t kSizeOf_EVP_MD_CTX = 48;+constexpr size_t kSizeOf_EVP_PKEY = 72;+constexpr size_t kSizeOf_EVP_PKEY_CTX = 80;+constexpr size_t kSizeOf_HMAC_CTX = 32;++// Define smart pointers for the most commonly used OpenSSL types:+using X509Pointer = DeleteFnPtr<X509, X509_free>;+using BIOPointer = DeleteFnPtr<BIO, BIO_free_all>;+using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>;+using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;+using SSLPointer = DeleteFnPtr<SSL, SSL_free>;+using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;+using EVPKeyPointer = DeleteFnPtr<EVP_PKEY, EVP_PKEY_free>;+using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;+using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;+using RSAPointer = DeleteFnPtr<RSA, RSA_free>;+using ECPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;+using BignumPointer = DeleteFnPtr<BIGNUM, BN_free>;+using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;+using ECGroupPointer = DeleteFnPtr<EC_GROUP, EC_GROUP_free>;+using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>;+using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;+using DHPointer = DeleteFnPtr<DH, DH_free>;+using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;+using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;+using CipherCtxPointer = DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>;+using RsaPointer = DeleteFnPtr<RSA, RSA_free>;+using DsaPointer = DeleteFnPtr<DSA, DSA_free>;++// Our custom implementation of the certificate verify callback+// used when establishing a TLS handshake. Because we cannot perform+// I/O quickly enough with X509_STORE_CTX_ APIs in this callback,+// we ignore preverify_ok errors here and let the handshake continue.+// In other words, this VerifyCallback is a non-op. It is imperative+// that the user user Connection::VerifyError after the `secure`+// callback has been made.+extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);++void InitCryptoOnce();++void InitCrypto(v8::Local<v8::Object> target);++extern void UseExtraCaCerts(const std::string& file);++unsigned long SetFips(bool on = true);  // NOLINT(runtime/int)++// Forcibly clear OpenSSL's error stack on return. This stops stale errors+// from popping up later in the lifecycle of crypto operations where they+// would cause spurious failures. It's a rather blunt method, though.+// ERR_clear_error() isn't necessarily cheap either.+struct ClearErrorOnReturn {+  inline ~ClearErrorOnReturn() { ERR_clear_error(); }+};++// Pop errors from OpenSSL's error stack that were added+// between when this was constructed and destructed.+struct MarkPopErrorOnReturn {+  inline MarkPopErrorOnReturn() { ERR_set_mark(); }+  inline ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }+};++// Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.+// The entropy pool starts out empty and needs to fill up before the PRNG+// can be used securely.  Once the pool is filled, it never dries up again;+// its contents is stirred and reused when necessary.+//+// OpenSSL normally fills the pool automatically but not when someone starts+// generating random numbers before the pool is full: in that case OpenSSL+// keeps lowering the entropy estimate to thwart attackers trying to guess+// the initial state of the PRNG.+//+// When that happens, we will have to wait until enough entropy is available.+// That should normally never take longer than a few milliseconds.+//+// OpenSSL draws from /dev/random and /dev/urandom.  While /dev/random may+// block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't+// block under normal circumstances.+//+// The only time when /dev/urandom may conceivably block is right after boot,+// when the whole system is still low on entropy.  That's not something we can+// do anything about.+void CheckEntropy();++// Generate length bytes of random data. If this returns false, the data+// may not be truly random but it's still generally good enough.+bool EntropySource(unsigned char* buffer, size_t length);++int PasswordCallback(char* buf, int size, int rwflag, void* u);++int NoPasswordCallback(char* buf, int size, int rwflag, void* u);++template <typename T>+void Decode(const v8::FunctionCallbackInfo<v8::Value>& args,+            void (*callback)(T*, const v8::FunctionCallbackInfo<v8::Value>&,+                             const char*, size_t)) {+  T* ctx;+  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());++  if (args[0]->IsString()) {+    StringBytes::InlineDecoder decoder;+    Environment* env = Environment::GetCurrent(args);+    enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);+    if (decoder.Decode(env, args[0].As<v8::String>(), enc).IsNothing())+      return;+    callback(ctx, args, decoder.out(), decoder.size());+  } else {+    ArrayBufferViewContents<char> buf(args[0]);+    callback(ctx, args, buf.data(), buf.length());+  }+}++// Utility struct used to harvest error information from openssl's error stack+struct CryptoErrorVector : public std::vector<std::string> {+  void Capture();++  v8::MaybeLocal<v8::Value> ToException(+      Environment* env,+      v8::Local<v8::String> exception_string = v8::Local<v8::String>()) const;+};++// A helper class representing a read-only byte array. When deallocated, its+// contents are zeroed.+class ByteSource {+ public:+  ByteSource() = default;+  ByteSource(ByteSource&& other) noexcept;+  ~ByteSource();++  ByteSource& operator=(ByteSource&& other) noexcept;++  const char* get() const;++  template <typename T>+  const T* data() const { return reinterpret_cast<const T*>(get()); }++  size_t size() const;++  inline operator bool() const {+    return data_ != nullptr;+  }++  inline BIGNUM* ToBN() const {

Nope, in fact that's the right thing. Fixing.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 using v8::Value; namespace crypto { namespace Timing { +struct BigIntInfo {+  int sign_bit;+  int word_count;+  std::unique_ptr<uint64_t> words;

std::vector is better.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 using v8::Value; namespace crypto { namespace Timing { +struct BigIntInfo {+  int sign_bit;+  int word_count;+  std::unique_ptr<uint64_t> words;+};++void TimingSafeEqualBigInt(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  if (!args[0]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val1\" argument must be a bigint.");+    return;+  }+  if (!args[1]->IsBigInt()) {+    THROW_ERR_INVALID_ARG_TYPE(+      env, "The \"val2\" argument must be a bigint.");+    return;+  }++  BigIntInfo inf1 {};+  BigIntInfo inf2 {};++  Local<v8::BigInt> b1 = args[0].As<v8::BigInt>();+  Local<v8::BigInt> b2 = args[1].As<v8::BigInt>();++  inf1.word_count = b1->WordCount();+  inf2.word_count = b2->WordCount();++  if (inf1.word_count != inf2.word_count)+    return args.GetReturnValue().Set(false);++  inf1.words.reset(Malloc<uint64_t>(inf1.word_count));+  inf2.words.reset(Malloc<uint64_t>(inf1.word_count));++  b1->ToWordsArray(&inf1.sign_bit, &inf1.word_count, inf1.words.get());+  b2->ToWordsArray(&inf2.sign_bit, &inf2.word_count, inf2.words.get());

We should be fine.

When creating a BitInt instance from JavaScript, unless I've missed something entirely, there's no way of creating one with extraneous zero words, and the way that the internal representation works, leading zero words are part of the value and trailing zero words are truncated.

For instance, if I create a BigInt using:

uint64_t words[] = { 0UL, 0UL, 0UL, 1UL };
Local<BigInt> test;
if (BigInt::NewFromWords(env->context(), 0, arraysize(words), words).ToLocal(&test_bn)) {
  // ...
}

The value of the BigInt is 6277101735386680763835789423207666416102355444464034512896, and the word count is 4, as expected.

However, if I create a BigInt using...

uint64_t words[] = { 1UL, 0UL, 0UL, 0UL };
Local<BigInt> test;
if (BigInt::NewFromWords(env->context(), 0, arraysize(words), words).ToLocal(&test_bn)) {
  // ...
}

The value of the BigInt is 1, and the word count is 1.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

+#include "crypto/crypto_aes.h"+#include "crypto/crypto_cipher.h"+#include "crypto/crypto_keys.h"+#include "crypto/crypto_util.h"+#include "allocated_buffer-inl.h"+#include "async_wrap-inl.h"+#include "base_object-inl.h"+#include "env-inl.h"+#include "memory_tracker-inl.h"+#include "threadpoolwork-inl.h"+#include "v8.h"++#include <openssl/bn.h>+#include <openssl/aes.h>++#include <vector>++namespace node {++using v8::FunctionCallbackInfo;+using v8::Local;+using v8::Object;+using v8::Uint32;+using v8::Value;++namespace crypto {++namespace {+// Implements general AES encryption and decryption for multiple modes.+// The key_data must be a secret key.+// On success, this function sets out to a new AllocatedBuffer+// instance containing the results and returns WebCryptoCipherStatus::ERR_OK.+WebCryptoCipherStatus AES_Cipher(+    Environment* env,+    KeyObjectData* key_data,+    WebCryptoCipherMode cipher_mode,+    const AESCipherConfig& params,+    const ByteSource& in,+    AllocatedBuffer* out) {+  CHECK_NOT_NULL(key_data);+  CHECK_EQ(key_data->GetKeyType(), kKeyTypeSecret);++  const int mode = EVP_CIPHER_mode(params.cipher);++  CipherCtxPointer ctx(EVP_CIPHER_CTX_new());+  EVP_CIPHER_CTX_init(ctx.get());+  if (mode == EVP_CIPH_WRAP_MODE)+    EVP_CIPHER_CTX_set_flags(ctx.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);++  const bool encrypt = cipher_mode == kWebCryptoCipherEncrypt;++  if (!EVP_CipherInit_ex(+          ctx.get(),+          params.cipher,+          nullptr,+          nullptr,+          nullptr,+          encrypt)) {+    // Cipher init failed+    return WebCryptoCipherStatus::ERR_FAILED;+  }++  if (!EVP_CIPHER_CTX_set_key_length(+          ctx.get(),+          key_data->GetSymmetricKeySize()) ||+      !EVP_CipherInit_ex(+          ctx.get(),+          nullptr,+          nullptr,+          reinterpret_cast<const unsigned char*>(key_data->GetSymmetricKey()),+          params.iv.data<unsigned char>(),+          encrypt)) {+    return WebCryptoCipherStatus::ERR_FAILED;+  }++  size_t tag_len = 0;++  if (mode == EVP_CIPH_GCM_MODE) {+    switch (cipher_mode) {+      case kWebCryptoCipherDecrypt:+        // If in decrypt mode, the auth tag must be set in the params.tag.+        CHECK(params.tag);+        if (!EVP_CIPHER_CTX_ctrl(+                ctx.get(),+                EVP_CTRL_AEAD_SET_TAG,+                params.tag.size(),+                const_cast<char*>(params.tag.get()))) {+          return WebCryptoCipherStatus::ERR_FAILED;+        }+        break;+      case kWebCryptoCipherEncrypt:+        // In decrypt mode, we grab the tag length here. We'll use it to+        // ensure that that allocated buffer has enough room for both the+        // final block and the auth tag. Unlike our other AES-GCM implementation+        // in CipherBase, in WebCrypto, the auth tag is concatentated to the end+        // of the generated ciphertext and returned in the same ArrayBuffer.+        tag_len = params.length;+        break;+      default:+        UNREACHABLE();+    }+  }++  size_t total = 0;+  int buf_len = in.size() + EVP_CIPHER_CTX_block_size(ctx.get()) + tag_len;+  int out_len;++  AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, buf_len);+  unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());++  if (!EVP_CipherUpdate(+          ctx.get(),+          data,+          &out_len,+          in.data<unsigned char>(),+          in.size())) {+    return WebCryptoCipherStatus::ERR_FAILED;+  }++  total += out_len;+  CHECK_LE(out_len, buf_len);+  data += out_len;+  out_len = EVP_CIPHER_CTX_block_size(ctx.get());+  if (!EVP_CipherFinal_ex(ctx.get(), data, &out_len)) {+    return WebCryptoCipherStatus::ERR_FAILED;+  }+  total += out_len;++  // If using AES_GCM, grab the generated auth tag and append+  // it to the end of the ciphertext.+  if (cipher_mode == kWebCryptoCipherEncrypt && mode == EVP_CIPH_GCM_MODE) {+    data += out_len;+    if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG, tag_len, data))+      return WebCryptoCipherStatus::ERR_FAILED;+    total += tag_len;+  }++  // It's possible that we haven't used the full allocated space. Size down.+  buf.Resize(total);+  *out = std::move(buf);++  return WebCryptoCipherStatus::ERR_OK;+}++// The AES_CTR implementation here takes it's inspiration from the chromium+// implementation here:+// https://github.com/chromium/chromium/blob/master/components/webcrypto/algorithms/aes_ctr.cc++template <typename T>+T CeilDiv(T a, T b) {+  return a == 0 ? 0 : 1 + (a - 1) / b;

Possibly. This is pull directly from the equivalent chromium implementation as the comments note. I'll likely be revisiting this to see if there's a different way of implementing as I'm not 100% happy with the way this is now.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 crypto.randomFill(buf, 5, 5, (err, buf) => { }); ``` -Any `TypedArray` or `DataView` instance may be passed as `buffer`.+Any `ArrayBuffer` `TypedArray` or `DataView` instance may be passed as

Specifically the WebCrypto API spec refers to https://heycam.github.io/webidl/#dfn-get-buffer-source-copy, and is confirmed by both the MDN documentation and experimentation with all the browser implementations. supporting ArrayBuffer as input is required.

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

+# Node.js src/crypto Documentation++Welcome. You've found your way to the Node.js native crypto subsystem.++Do not be afraid.++While crypto may be a dark, mysterious, and forboding subject; and while+this directory may be filled with many `*.h` and `*.cc` files, finding+your way around is not too difficult. And I can promise you that a Gru+will not jump out of the shadows and eat you (well, "promise" may be a+bit too strong, a Gru may jump out of the shadows and eat you if you+live in a place where such things are possible).++## Finding your way around++All of the code in this directory is structured into units organized by+function or crypto protocol.++The following provide generalized utility declarations that are used throughout+the various other crypto files and other parts of Node.js:++* `crypto_util.h` / `crypto_util.cc` (Core crypto definitions)+* `crypto_common.h` / `crypto_common.h` (Shared TLS utility functions)+* `crypto_bio.c` / `crypto_bio.c` (Custom OpenSSL i/o implementation)+* `crypto_groups.h` (modp group definitions)++Of these, `crypto_util.h` and `crypto_util.cc` are the most important, as+they provide the core declarations and utility functions used most extensively+throughout the rest of the code.++The rest of the files are structured by their function, as detailed in the+following table:++| File (*.h/*.cc) | Description |+| --------------- | ----------------- |+| `crypto_cipher`      | General Encryption/Decryption utilities. |+| `crypto_clienthello` | TLS/SSL client hello parser implementation. Used during SSL/TLS handshake. |+| `crypto_context`     | Implementation of the `SecureContext` object. |+| `crypto_dh`          | Diffie-Hellman Key Agreement implementation. |+| `crypto_dsa`         | DSA (Digital Signature) Key Generation functions. |+| `crypto_ecdh`        | Elliptic-Curve Diffie-Hellman Key Agreement implementation. |+| `crypto_hash`        | Basic hash (e.g. SHA-256) functions. |+| `crypto_hkdf`        | HKDF (Key derivation) implementation. |+| `crypto_hmac`        | HMAC implementations. |+| `crypto_keys`        | Utilities for using and generating secret, private, and public keys. |+| `crypto_pbkdf2`      | PBKDF2 key / bit generation implementation. |+| `crypto_rsa`         | RSA Key Generation functions. |+| `crypto_scrypt`      | Scrypt key / bit generation implementation. |+| `crypto_sig`         | General digital signature and verification utilities. |+| `crypto_spkac`       | Netscape SPKAC certificate utilities. |+| `crypto_ssl`         | Implementation of the `SSLWrap` object. |+| `crypto_timing`      | Implementation of the TimingSafeEqual. |++When new crypto protocols are added, they will be added into their own+`crypto_` `*.h` and `*.cc` files.++## Helpful concepts++Node.js currently uses OpenSSL to provide it's crypto substructure.+(Some custom Node.js distributions -- such as Electron -- use BoringSSL+instead.)++This section aims to explain some of the utilities that have been+provided to make working with the OpenSSL APIs a bit easier.++### Pointer Types++Most of the key OpenSSL types need to be explicitly freed when they are+no longer needed. Failure to do so introduces memory leaks. To make this+easier (and less error prone), the `crypto_util.h` defines a number of+smart-pointer aliases that should be used:++```cpp+using X509Pointer = DeleteFnPtr<X509, X509_free>;+using BIOPointer = DeleteFnPtr<BIO, BIO_free_all>;+using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>;+using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;+using SSLPointer = DeleteFnPtr<SSL, SSL_free>;+using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;+using EVPKeyPointer = DeleteFnPtr<EVP_PKEY, EVP_PKEY_free>;+using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;+using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;+using RSAPointer = DeleteFnPtr<RSA, RSA_free>;+using ECPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;+using BignumPointer = DeleteFnPtr<BIGNUM, BN_free>;+using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;+using ECGroupPointer = DeleteFnPtr<EC_GROUP, EC_GROUP_free>;+using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>;+using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;+using DHPointer = DeleteFnPtr<DH, DH_free>;+using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;+using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;+using CipherCtxPointer = DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>;+```++Examples of these being used are pervasive through the `src/crypto` code.++### `ByteSource`++The `ByteSource` class is a helper utility representing a *read-only* byte+array. Instances can either wrap external ("foreign") data sources, such as+an `ArrayBuffer` (`v8::BackingStore`) or allocated data. If allocated data+is used, then the allocation is freed automatically when the `ByteSource` is+destroyed.++### `ArrayBufferOrViewContents`++The `ArrayBufferOfViewContents` class is a helper utility that abstracts+`ArrayBuffer`, `TypedArray`, or `DataView` inputs and provides access to+their underlying data pointers. It is used extensively through `src/crypto`+to make it easier to deal with inputs that allow any `ArrayBuffer`-backed+object.++### `AllocatedBuffer`++The `AllocatedBuffer` utility is defined in `allocated_buffer.h` and is not+specific to `src/crypto`. It is used extensively within `src/crypto`, however,+to hold allocated data that is intended to be output in response to various+crypto functions.

For now we need it. But this is one of the points I'd like to resolve. If we can transition sec/crypto to use the BackingStore now, that would be ideal to avoid the later change

jasnell

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

 crypto.randomFill(buf, 5, 5, (err, buf) => { }); ``` -Any `TypedArray` or `DataView` instance may be passed as `buffer`.+Any `ArrayBuffer` `TypedArray` or `DataView` instance may be passed as

Yes, WebCrypto requires that ArrayBuffer be supported. Accordingly, it makes sense to support them also in the legacy API since the underlying code is going to need to support them.

jasnell

comment created time in 4 days

PullRequestReviewEvent

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

@tniessen @addaleax @nodejs/crypto ... while this is not yet complete, it's far enough along to start review.

jasnell

comment created time in 5 days

push eventjasnell/node

James M Snell

commit sha cde6a30719afe66916c38a2d6565cfe8ef75c309

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

James M Snell

commit sha e0dafc88c3fdd6ff413f8e691096b9220462c900

crypto: add timingSafeEqual.bigint Variation on timingSafeEqual that uses a constant time algorithm to compare bigints.

view details

push time in 5 days

push eventjasnell/node

James M Snell

commit sha e2a227bffb9ce940cc784dbfa3c42aa6bc462849

crypto: add timingSafeEqual.bigint Variation on timingSafeEqual that uses a constant time algorithm to compare bigints.

view details

push time in 5 days

push eventjasnell/node

James M Snell

commit sha a6e42fb706a17b497a79cdd8c27d3fb3092096fd

crypto: refactoring internals, add WebCrypto Fixes: https://github.com/nodejs/node/issues/678 Refs: https://github.com/nodejs/node/issues/26854 Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 5 days

push eventjasnell/node

James M Snell

commit sha a1726351a9d1c5f40c2712213a401c06d0cecf91

crypto: refactoring internals, add WebCrypto Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 5 days

issue commentnodejs/node

crypto: DH prime for bits <= 15 is always 35963

@bnoordhuis ... in current master this appears to be fixed in 12.x, 14.x and master with a couple of exceptions:

  1. When bits is <= 8, getPrime() can return a Buffer with 1 or 2 bytes (causing your tests to fail because they assume at least two bytes)
  2. bits 3 and 4 always produce the same result (0x0b)
  3. bits 5 and 6 always produce the same result (0x3b)
  4. getPrime() does not start producing reliably variable results until bits 7 at least.

It is still an issue in 10.x

bnoordhuis

comment created time in 5 days

push eventjasnell/node

James M Snell

commit sha 4bc34cb5050149866799026be0d6d3fd2accc66c

...

view details

push time in 5 days

issue closedcovidgreen/covid-green-infra

Nominating @ninjatux as a contributor

Working with Valerio on a daily basis on features of the infrastructure repo.

closed time in 5 days

pmcgrath

issue commentcovidgreen/covid-green-infra

Nominating @ninjatux as a contributor

Added

pmcgrath

comment created time in 5 days

push eventjasnell/node

James M Snell

commit sha 42a93380341fc43da440fbfdb5c1517c195309cc

...

view details

push time in 5 days

push eventjasnell/node

James M Snell

commit sha 1fabe6973974edb6aeb5a603829849cebd9dee94

crypto: refactoring internals, add WebCrypto Signed-off-by: James M Snell <jasnell@gmail.com>

view details

push time in 5 days

push eventjasnell/node

Tom Atkinson

commit sha d4aac8399247ceb57cc517cb51ccdb24696ab4b5

doc: fix missing word in dgram.md The word "cannot" is missing from this sentence PR-URL: https://github.com/nodejs/node/pull/35231 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>

view details

Beth Griggs

commit sha 524123fbf064ff64bb6fcd83485cfc27db932f68

doc: update releaser in v12.18.4 changelog PR-URL: https://github.com/nodejs/node/pull/35217 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>

view details

Rich Trott

commit sha 18462e0c1d5f3b3a3e86b7b40fb65975f1e27381

doc: replace "you should do X" with "do X" PR-URL: https://github.com/nodejs/node/pull/35194 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>

view details

Rich Trott

commit sha c205f672e9cf0c70ea26f87eb97342947a244e18

doc: use command-line/command line consistently Docs switch between "command line" and "command-line" with no apparent uniformity. Microsoft Style Guide prescribes "command line" as a noun and "command-line" as a modifier, which makes a lot of sense to me. Updating docs as appropriate. PR-URL: https://github.com/nodejs/node/pull/35198 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha 72e20298116d24baaf05f4dd0a0c997f1138b0c2

doc: remove "end user" We use "end user" in ambiguous ways. Sometimes we mean the developer, and sometimes we mean the application user. Use "developer" where developer is meant. Refs: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/u/user-end-user PR-URL: https://github.com/nodejs/node/pull/35200 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>

view details

James M Snell

commit sha 1634643ad0a538e8bb612202e307b99fcac798c3

subtle

view details

push time in 5 days

push eventjasnell/node

James M Snell

commit sha face36096bd46280a27e558e4883e293f8621d72

subtle

view details

push time in 5 days

MemberEvent

push eventjasnell/specs

Julian Reschke

commit sha 6b285c92ddeba53a7423835f1539e9b5f9210790

search: refresh document (#6) * add -latest version * chmod * fix version and date * fix area, workgroup and keywords * remove unneeded title abbrev * avoid xref in abstract * add "updates: 5323" * use v3 markup * remove unused references * add Editorial Note * use v3 markup for deep link * switch to v3 backend, fix ipr attribute * update contact info for Julian and Ashok * use xi:include

view details

push time in 5 days

PR merged jasnell/specs

search: refresh document
+395 -0

2 comments

1 changed file

reschke

pr closed time in 5 days

pull request commentjasnell/specs

search: refresh document

Oh hey, sorry about that, I completely missed the original notification. I'll merge this then give you commit access in a bit.

reschke

comment created time in 5 days

push eventjasnell/node

James M Snell

commit sha 7dc8aa2f58b53c94a79a033f379656cc7a4633dc

subtle

view details

push time in 6 days

push eventjasnell/node

Rich Trott

commit sha 4c9b79ed5a776b6e1b99703ec9976312ae9b5fae

doc: avoid double-while sentence in perf_hooks.md This improves readability, as well as awkward reptition of the word _while_ with two different meanings in a single sentence. Refs: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/w/while PR-URL: https://github.com/nodejs/node/pull/35078 Reviewed-By: Denys Otrishko <shishugi@gmail.com> Reviewed-By: Derek Lewis <DerekNonGeneric@inf.is>

view details

Rich Trott

commit sha 661b770e11cd6d7decfb3232037ff1ba00efdbe4

doc: restore color for visited links A previous change altered the rendering of visited links. This restores it. PR-URL: https://github.com/nodejs/node/pull/35108 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Derek Lewis <DerekNonGeneric@inf.is> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>

view details

Tobias Nießen

commit sha a03e15f571dc54455896489589504df7ce45a0c8

doc: add note about path.basename on Windows PR-URL: https://github.com/nodejs/node/pull/35065 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Rich Trott

commit sha 7fc1a4a893e080d0e55d7af9638938d00889dc24

test: revise test-policy-integrity * eliminate unneeded Set deletion/cleanup * use number of CPUs as limit for processes spawned rather than hard-coding the limit PR-URL: https://github.com/nodejs/node/pull/35101 Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>

view details

Richard Lau

commit sha b7f3e8308661c3e370b4ebb863109655653d106f

2020-09-10, Version 14.10.1 (Current) Notable changes: Node.js 14.10.0 included a streams regression with async generators and a docs rendering regression that are being fixed in this release. PR-URL: https://github.com/nodejs/node/pull/35137

view details

himself65

commit sha 22c52aac6ace9154e9424c2994289ee4dde12bab

module: fix specifier resolution option value Fixes: https://github.com/nodejs/node/issues/35095 PR-URL: https://github.com/nodejs/node/pull/35098 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Rich Trott

commit sha 2f6bf7a79124e76792c7bbdf344009e214bd051b

doc: fix broken links in deprecations.md PR-URL: https://github.com/nodejs/node/pull/35109 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha e0a3faeff7cde1fa183a6efc3a3b3167deabd420

doc: fix broken link in fs.md PR-URL: https://github.com/nodejs/node/pull/35111 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha 85624fd12971ec50fd8bb26b70c3b04170577d1e

doc: fix broken link in http2.md PR-URL: https://github.com/nodejs/node/pull/35112 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ricky Zhou <0x19951125@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Derek Lewis <DerekNonGeneric@inf.is> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha 4f176c911097b3972328e703238d1fec0460e554

doc: fix broken link in perf_hooks.md PR-URL: https://github.com/nodejs/node/pull/35113 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Anna Henningsen

commit sha 02e925553d079c1e70b48e5255503d8850eb1fc5

doc,test: specify and test CLI option precedence rules Refs: https://github.com/nodejs/node/pull/35098#issuecomment-689051526 PR-URL: https://github.com/nodejs/node/pull/35106 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Zeyu Yang <himself65@outlook.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Guy Bedford

commit sha 3fb7fcd821a9aea27a19ef5f7ffcf5120acb859a

esm: better package.json parser errors PR-URL: https://github.com/nodejs/node/pull/35117 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Michael Dawson

commit sha 64b05a4b402d984fa9c849b7ea370d6fa18f519a

doc: update security process - update security process to reflect current way to request tweet/retweet of security release Signed-off-by: Michael Dawson <mdawson@devrus.com> PR-URL: https://github.com/nodejs/node/pull/35107 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Ash Cripps <ashley.cripps@ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

cjihrig

commit sha 636c0bb419907188308c01992e546ab1628bc556

deps: update to uvwasi 0.0.11 Notable changes: - Several issues have been addressed in uvwasi_fd_readdir(). A bug in the copying of the directory entry's name has been fixed. The function now returns UVWASI_ENOSYS on Windows and Android. Serdes support has been added for uvwasi_dirent_t's. - The libuv dependency has been updated to v1.39.0. PR-URL: https://github.com/nodejs/node/pull/35104 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Anna Henningsen

commit sha 8a8ca4b0bf123c708130a1152e960a9310c2ccc4

doc: add missing changes entry for breakEvalOnSigint REPL option PR-URL: https://github.com/nodejs/node/pull/35143 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Denys Otrishko

commit sha c66e6471e780e752f3f6f9337ac49a3d6e3d7091

lib: remove ERR_INVALID_OPT_VALUE and ERR_INVALID_OPT_VALUE_ENCODING This will be a start to generalize all argument validation errors. As currently we throw ARG/OPT, OUT_OF_RANGE, and other more specific errors. The OPT errors didn't bring much to the errors as it's just another variant of ARG error which is sometimes more confusing (some of our code used OPT errors to denote just argument validation errors presumably because of similarity of OPT to 'option' and not 'options-object') and they don't specify the name of the options object where the invalid value is located. Much better approach would be to just specify path to the invalid value in the name of the value as it is done in this PR (i.e. 'options.format', 'options.publicKey.type' etc) Also since this decreases a variety of errors we have it'd be easier to reuse validation code across the codebase. Refs: https://github.com/nodejs/node/pull/31251 Refs: https://github.com/nodejs/node/pull/34070#discussion_r467251009 Signed-off-by: Denys Otrishko <shishugi@gmail.com> PR-URL: https://github.com/nodejs/node/pull/34682 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Denys Otrishko

commit sha b1831fed3a289d883944d23d2130368d90a48be2

events: simplify event target agnostic logic in on and once PR-URL: https://github.com/nodejs/node/pull/34997 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>

view details

Michael Dawson

commit sha 91272bce7a5c98829f4a2736def1d684c8f8eb1b

doc: update my email address Update email address to reflect move to Red Hat Signed-off-by: Michael Dawson <mdawson@devrus.com> PR-URL: https://github.com/nodejs/node/pull/35121 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Rich Trott

commit sha f54254afedd5a2b4800854e7766d845e3803bef6

errors: simplify ERR_REQUIRE_ESM message generation Because of the condition that starts the `if` block, we know that `parentPath` must be truthy. So there is no need to check for that in the template string that generates the error message. PR-URL: https://github.com/nodejs/node/pull/35123 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com>

view details

Rich Trott

commit sha 1df50ffb556b4d751942dfcb753f90c58dcf9e74

doc: simplify circular dependencies text in modules.md PR-URL: https://github.com/nodejs/node/pull/35126 Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

push time in 6 days

PullRequestReviewEvent

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

Nice! I should have this pr ready for review by end of this week.

jasnell

comment created time in 8 days

PullRequestReviewEvent

pull request commentnodejs/node

doc: drop minimum waiting time as hard guideline

@nodejs/tsc ... To resolve this we're going to need tsc to weigh in with a possible vote. Based on the conversation, I'm seeing three basic options

  1. Status quo. Leave the time limits as they are
  2. Remove all time limits as suggested by this pr
  3. Reduce the current time limits to 24 hours with two sign offs, at least one of which is from relevant CODEOWNERS team, or 72 hours with one sign off.

If there are additional choices, please say so. I'm requesting that we schedule time during an upcoming tsc meeting to discuss and if we can't come to a resolution, put it to a vote.

addaleax

comment created time in 9 days

pull request commentnodejs/node

crypto: fix size_t/int regression node_crypto

I'll work on that in the crypto refactor I'm doing and will get it backported for 14 and 12 also. Thanks Ben.

jasnell

comment created time in 10 days

PullRequestReviewEvent

pull request commentnodejs/node

crypto: fix size_t/int regression node_crypto

With this PR, the range checking is too much all over the place, making it harder to get it right.

In a separate PR I'm making much more far reaching changes that should make it significantly easier to deal with moving forward. It does not yet centralize the type checking / length checking but that's something that can be done easily.

I am perfectly fine with an across-the-board restriction for all crypto operation lengths to be <= INT_MAX

Forgot to mention: the alternative is to have Node.js transparently break up operations over ranges > INT_MAX into smaller ones but that's error prone, might not always be possible, and probably so exceedingly rare as to not be worth the effort.

Yeah, I had considered this also and ruled it out for the same reason.

jasnell

comment created time in 12 days

push eventjasnell/node

James M Snell

commit sha 399f61d1ab40c6931380bf9875ed0e629cfc025c

[squash] nit Co-authored-by: Denys Otrishko <shishugi@gmail.com>

view details

push time in 12 days

push eventjasnell/node

James M Snell

commit sha 4e2952eb52be6c2c865dc0024135d218b684c160

subtle

view details

push time in 12 days

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

@panva:

I would be very careful with extending WebCrypto with custom algorithms as the proprietary unregistered algs may clash and confuse developers thinking it's part of WebCrypto

Caution will definitely be waranted and any such extension will be in line with the extensibility guidelines of the spec (https://www.w3.org/TR/WebCryptoAPI/#extensibility). Specifically, any Node.js specific algorithms would be prefixed as such when used. For instance...

const { subtle } = require('crypto/promises');
const ec = new TextEncoder();

subtle.digest({ name: 'node.shake256', length: 100 }, ec.encode('hello'));

For well-known algorithms like Scrypt and CMAC, my intention would be to introduce those initially as node-prefixed algorithms e.g. {name: 'node-cmac' } and simultaneously open a proposal to have those added to the standard directly.

One alternative that I'm considering is exposing a separate NodeSubtleCrypto class off require('crypto/promises') that extends SubtleCrypto with the addition of the Node.js-specific extensions.

So, for instance, with this alternative, the following would fail:

const { subtle } = require('crypto/promises');
const ec = new TextEncoder();

subtle.digest({ name: 'node.shake256', length: 100 }, ec.encode('hello'));

But this would work:

const { nodeSubtle } = require('crypto/promises');
const ec = new TextEncoder();

nodeSubtle.digest({ name: 'node.shake256', length: 100 }, ec.encode('hello'));

In either case, developers will have to explicitly opt in to using the Node.js specific extensions.

jasnell

comment created time in 12 days

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

@targos:

Do you plan to integrate the WebCryptoAPI web platform tests?

Absolutely, but that will likely be in a follow on PR.

jasnell

comment created time in 12 days

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

Yes, the goal is 100% compatibility with the Web Crypto API. The CryptoKey object is a wrapper around the existing KeyObject. Allowing conversion between the two using importKey and exportKey is a good idea. Buffer will be supported but is treated as if it is any other TypedArray.

Once the basic algorithms required by the WebCrypto spec are implemented, support for the broader range of algorithms we support in the legacy API will be added, starting with a few we already support such as scrypt, DH (non-ECDH), all of the ciphers, hashes, and curves reported in the getHashes, getCiphers, and getCurves APIs, and all of the keygen types supported by the existing generateKeyPair API. This will take some effort as they will be integrated into the extensible framework already provided by WebCrypto. Anything that does not fit within the WebCrypto API will be exposed directly off the crypto/promises module and not the SubtleCrypto class.

After that, I have plans for a few new algorithms we do not currently support in either API. CMAC for instance. And possibly UUID and simple HOTP/TOTP based token generation. Once the changes here are completed, it will be far easier to incorporate such additions.

jasnell

comment created time in 12 days

issue commentcovidgreen/covid-green-app

Potential memory leak in services/api/index.ts

Certainly!

jasnell

comment created time in 13 days

issue commentpiscinajs/piscina

Progress

Good idea! Yeah, I'll get something added shortly!

Zack-Heisnberg

comment created time in 13 days

pull request commentnodejs/node

[WIP] crypto: refactor crypto subsystem and introduce WebCrypto API

For anyone curious about the performance difference that the SubtleCrypto APIs will have relative to the legacy apis... Here's an example comparing crypto.createHash() to subtle.digest() ...

Keep in mind, however, that this is tracking raw execution speed, and ignores factors such as event loop delay, event loop utilization and memory. The createHash variant is purely sync, while the subtle version uses the libuv threadpool.

crypto/webcrypto-digest.js n=1000 method="SHA-1" data=10 sync="createHash": 94,602.60002001791
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=10 sync="createHash": 20,070.058150585086
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=10 sync="createHash": 55,681.77686340876
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=10 sync="createHash": 43,733.5794076068
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=20 sync="createHash": 70,726.74488714593
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=20 sync="createHash": 52,796.95289777924
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=20 sync="createHash": 92,470.48873704823
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=20 sync="createHash": 36,330.60193812862
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=50 sync="createHash": 93,567.16391376476
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=50 sync="createHash": 95,433.87100776259
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=50 sync="createHash": 69,989.07610500153
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=50 sync="createHash": 86,632.92891638233
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=100 sync="createHash": 62,713.004720533296
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=100 sync="createHash": 92,227.69542356953
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=100 sync="createHash": 58,363.47758314272
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=100 sync="createHash": 91,339.97478468656
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=10 sync="subtle": 13,358.364593130998
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=10 sync="subtle": 32,006.11342371284
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=10 sync="subtle": 22,250.87690149597
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=10 sync="subtle": 20,624.592264701296
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=20 sync="subtle": 51,008.840087031276
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=20 sync="subtle": 14,754.004273644876
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=20 sync="subtle": 46,213.40955095308
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=20 sync="subtle": 40,880.32676789835
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=50 sync="subtle": 22,610.031492156264
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=50 sync="subtle": 33,920.458018446894
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=50 sync="subtle": 48,910.4416554189
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=50 sync="subtle": 12,468.43351102472
crypto/webcrypto-digest.js n=1000 method="SHA-1" data=100 sync="subtle": 21,238.01034673388
crypto/webcrypto-digest.js n=1000 method="SHA-256" data=100 sync="subtle": 25,608.43004933131
crypto/webcrypto-digest.js n=1000 method="SHA-384" data=100 sync="subtle": 47,109.37798850117
crypto/webcrypto-digest.js n=1000 method="SHA-512" data=100 sync="subtle": 22,149.473507014736
jasnell

comment created time in 13 days

push eventjasnell/node

James M Snell

commit sha 13f1691a588f1d00af9ace6b477f42ba26100b0e

subtle

view details

push time in 13 days

push eventjasnell/node

James M Snell

commit sha 409f56ec59d6c3632c717bd3e67f835ada75775e

subtle

view details

push time in 13 days

push eventjasnell/node

James M Snell

commit sha 4dacf7fa2525d2803ee30025b73b9342a606f5f7

subtle

view details

push time in 13 days

push eventjasnell/node

Rich Trott

commit sha 665330134cafb6d40e39d134f3bef03b09fbd9ae

doc: make minor improvements to module.md * sort references in ASCII order * replace abbreviation * split comma splice into two sentences and add appropriate punctuation * replace future tense with present tense PR-URL: https://github.com/nodejs/node/pull/35083 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Derek Lewis <DerekNonGeneric@inf.is> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>

view details

Tobias Nießen

commit sha 1204400d6411694d08bde0c3c197c9a72b72f570

test: fix comment about DNS lookup test PR-URL: https://github.com/nodejs/node/pull/35080 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

Rich Trott

commit sha d7d0fab70e45f2866dd6db0a489540cbbf434b97

crypto: improve randomInt out-of-range error message Previously, the crypto.randomInt() message when "max" was less than or equal to "min" made it sound like the lower bound for "max" was hard-coded. Make it clear that it is instead dynamic based on the value of "min". For crypto.randomInt(10,0): Before: RangeError [ERR_OUT_OF_RANGE]: The value of "max" is out of range. It must be > 10. Received 0 After: RangeError [ERR_OUT_OF_RANGE]: The value of "max" is out of range. It must be greater than the value of "min" (10). Received 0 PR-URL: https://github.com/nodejs/node/pull/35088 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tobias Nießen <tniessen@tnie.de>

view details

Rich Trott

commit sha 40633351bc64a093a7e0a88b7e65a4c9e4a091f6

crypto: improve invalid arg type message for randomInt() Use "must be a safe integer" rather than "must be safe integer". I believe the former is more easily understood/clear. PR-URL: https://github.com/nodejs/node/pull/35089 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>

view details

Tobias Nießen

commit sha f07f4207522075fb5b3062afac24a19ecbb83825

test: remove setMaxListeners in test-crypto-random This appears to be a remnant from 413d38c43bc3fa6828e10c75736f81c3d6b7e944. PR-URL: https://github.com/nodejs/node/pull/35079 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>

view details

James M Snell

commit sha a3ce7f6af21b3fd9b56f95b52c7a1c3920372327

subtle

view details

push time in 13 days

push eventjasnell/node

James M Snell

commit sha 663f0a5881ebc91974abc877c71cba3f23b0ccff

subtle

view details

push time in 13 days

push eventjasnell/node

James M Snell

commit sha 4c8c193687b2ed9df5dfccd072d82909d6a20bbe

[Squash] fixup

view details

push time in 13 days

Pull request review commentnodejs/node

crypto: fix regression in randomFill/randomBytes

 function platformTimeout(ms) { }  let knownGlobals = [-  AbortController,+//  AbortController,
  AbortController,
jasnell

comment created time in 13 days

PullRequestReviewEvent

Pull request review commentnodejs/node

crypto: fix regression in randomFill/randomBytes

 function platformTimeout(ms) { }  let knownGlobals = [-  AbortController,+//  AbortController,

dangnabbit!!

jasnell

comment created time in 13 days

PullRequestReviewEvent

push eventjasnell/node

James M Snell

commit sha e0749dfaf8256425230faddb5a810d217071a599

fixup! crypto: fix regression in randomFill/randomBytes

view details

push time in 13 days

more