crypto: add FIPS indicator diagnostics channel · nodejs/node@d5d203a · GitHub
Skip to content

Commit d5d203a

Browse files
panvanodejs-github-bot
authored andcommitted
crypto: add FIPS indicator diagnostics channel
OpenSSL 3.4 added an indicator callback for operations that its FIPS provider allows after an approved-mode check has been relaxed. Publish these indicators on the crypto.fips.indicator diagnostics channel when Node.js is started with --enable-fips-indicator-events. Leave the OpenSSL callback unset otherwise so ordinary cryptographic operations have no indicator callback overhead. Keep the channel observation-only so enforcement remains the responsibility of the provider configuration, and independent diagnostic subscribers can coexist. Install the native callback during process initialization so it is not changed while Workers or thread-pool jobs can be using OpenSSL. Preserve callbacks installed by embedders, and queue bounded, coalesced messages for asynchronous delivery on the main environment. Document the channel as best-effort telemetry that cannot identify the originating call or establish FIPS validation. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #65645 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 2247054 commit d5d203a

15 files changed

Lines changed: 539 additions & 4 deletions

‎doc/api/cli.md‎

Lines changed: 13 additions & 0 deletions

‎doc/api/crypto.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7284,6 +7284,10 @@ startup. The following controls are also available:
72847284
fetched before the call are not changed.
72857285
* [`crypto.getFips()`][] reports the FIPS/property-query state. On OpenSSL 3, a
72867286
return value of `1` does not prove that a FIPS provider is loaded or validated.
7287+
* With [`--enable-fips-indicator-events`][], the
7288+
[`'crypto.fips.indicator'`][] diagnostics channel reports non-approved
7289+
operations permitted by an OpenSSL 3.4 or later FIPS provider configured for
7290+
backwards compatibility.
72877291

72887292
With OpenSSL 1.1.1, these controls use the library's FIPS mode support and
72897293
require a FIPS-capable OpenSSL build.
@@ -7612,7 +7616,9 @@ See the [list of SSL OP Flags][] for details.
76127616
[SIV and GCM-SIV modes]: #siv-and-gcm-siv-modes
76137617
[Web Crypto API documentation]: webcrypto.md
76147618
[XTS mode]: #xts-mode
7619+
[`'crypto.fips.indicator'`]: diagnostics_channel.md#event-cryptofipsindicator
76157620
[`--allow-openssl-store`]: cli.md#--allow-openssl-store
7621+
[`--enable-fips-indicator-events`]: cli.md#--enable-fips-indicator-events
76167622
[`--enable-fips`]: cli.md#--enable-fips
76177623
[`--force-fips`]: cli.md#--force-fips
76187624
[`--openssl-config`]: cli.md#--openssl-configfile

‎doc/api/diagnostics_channel.md‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,70 @@ passed to `console.warn()`.
15701570
Emitted when `console.error()` is called. Receives and array of the arguments
15711571
passed to `console.error()`.
15721572

1573+
#### Crypto
1574+
1575+
<!-- YAML
1576+
added: REPLACEME
1577+
-->
1578+
1579+
> Stability: 1 - Experimental
1580+
1581+
##### Event: `'crypto.fips.indicator'`
1582+
1583+
* `operation` {string} The provider-defined operation type.
1584+
* `reason` {string} The provider-defined description of why the operation is
1585+
not approved.
1586+
* `blocked` {boolean} Whether a native indicator callback installed before
1587+
Node.js blocked the operation.
1588+
* `count` {number} The number of matching pending indicator invocations
1589+
represented by this message.
1590+
* `dropped` {number} The number of additional indicator invocations dropped
1591+
before this message was delivered.
1592+
1593+
Emitted when the OpenSSL FIPS provider used by Node.js detects an operation that
1594+
is not FIPS approved after the corresponding provider check was relaxed. Such
1595+
operations are possible when the provider is configured for backwards
1596+
compatibility. The `operation` and `reason` values come from the provider and
1597+
should be treated as opaque strings rather than stable enumerations.
1598+
1599+
Start Node.js with [`--enable-fips-indicator-events`][] to enable this channel.
1600+
Without the option, subscribing does not install the OpenSSL callback and no
1601+
messages are published.
1602+
1603+
Subscribing to the channel is observation-only and never changes the result of
1604+
an operation. Node.js preserves the result from any native indicator callback
1605+
installed before Node.js initializes its crypto support.
1606+
1607+
Messages are published asynchronously on the main thread because OpenSSL
1608+
indicators can originate from Workers or other threads. Only subscriptions on
1609+
the main thread receive messages. Delivery order relative to the originating
1610+
operation is not defined, and a message cannot be correlated with a particular
1611+
call or Worker.
1612+
1613+
One cryptographic operation can invoke the OpenSSL indicator more than once.
1614+
Matching pending invocations are coalesced and reflected in `count`, which does
1615+
not necessarily represent a number of cryptographic operations. At most 256
1616+
distinct messages are queued. Additional invocations are reported in `dropped`
1617+
on the first queued message. Queued messages do not keep the event loop active,
1618+
so this channel is best-effort diagnostics rather than an authoritative audit
1619+
log.
1620+
1621+
This channel observes the default OpenSSL library context used by Node.js. It
1622+
does not observe native addons or other code that uses another `OSSL_LIB_CTX`
1623+
or another copy of `libcrypto`. It is active with OpenSSL 3.4 and later and is
1624+
not available with BoringSSL. A provider configured to reject a check directly,
1625+
including a pedantic OpenSSL FIPS provider, can reject an operation without
1626+
emitting an indicator. Receiving or not receiving a message does not establish
1627+
that Node.js or a cryptographic operation is FIPS validated.
1628+
1629+
```mjs
1630+
import diagnosticsChannel from 'node:diagnostics_channel';
1631+
1632+
diagnosticsChannel.subscribe('crypto.fips.indicator', (message) => {
1633+
console.error('Non-approved cryptographic operation', message);
1634+
});
1635+
```
1636+
15731637
#### HTTP
15741638

15751639
> Stability: 1 - Experimental
@@ -1963,6 +2027,7 @@ statement, since both are still in use while the event is being delivered; see
19632027
[BoundedChannel Channels]: #boundedchannel-channels
19642028
[TracingChannel Channels]: #tracingchannel-channels
19652029
[`'uncaughtException'`]: process.md#event-uncaughtexception
2030+
[`--enable-fips-indicator-events`]: cli.md#--enable-fips-indicator-events
19662031
[`BoundedChannel`]: #class-boundedchannel
19672032
[`DatabaseSync`]: sqlite.md#class-databasesync
19682033
[`TracingChannel`]: #class-tracingchannel

‎doc/node.1‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,12 @@ Enable FIPS mode at startup. With OpenSSL 3, a configured provider named
517517
\fBfips\fR must be available and initialize successfully. With OpenSSL 1.1.1,
518518
Node.js must be built against a FIPS-capable OpenSSL.
519519
.
520+
.It Fl -enable-fips-indicator-events
521+
Publish OpenSSL FIPS indicator results to the
522+
\fB'crypto.fips.indicator'\fR diagnostics channel. This option requires OpenSSL
523+
3.4 or later. It does not enable FIPS mode or change whether an operation
524+
is permitted.
525+
.
520526
.It Fl -enable-source-maps
521527
Enable Source Map support for stack traces.
522528
When using a transpiler, such as TypeScript, stack traces thrown by an
@@ -1978,6 +1984,8 @@ one is included in the list below.
19781984
.It
19791985
\fB--dns-result-order\fR
19801986
.It
1987+
\fB--enable-fips-indicator-events\fR
1988+
.It
19811989
\fB--enable-fips\fR
19821990
.It
19831991
\fB--enable-network-family-autoselection\fR

‎lib/internal/process/pre_execution.js‎

Lines changed: 7 additions & 2 deletions

0 commit comments

Comments
 (0)