Skip to content

Commit cd402cc

Browse files
authored
Lazily evaluate PQC support to prevent Node warnings on startup (#809)
This PR updates PQC support detection to only check for PQC support when a method that needs to know is actually invoked. Before, PQC support was checked by `SettingsService` when it was initialized. This lead to noisy warnings any time the Node process was started: **issue-807-prefix.mjs** ```js // @simplewebauthn/server@14.0.2 import { generateRegistrationOptions } from '@simplewebauthn/server'; ``` ```sh $ node issue-807-prefix.mjs (node:16420) ExperimentalWarning: The supports Web Crypto API method is an experimental feature and might change at any time (Use `node --trace-warnings ...` to show where the warning was created) (node:16420) ExperimentalWarning: The ML-DSA-44 Web Crypto API algorithm is an experimental feature and might change at any time ``` With these changes, a method needs to be actually invoked before the warnings will be displayed (if the runtime emits them): **issue-807-postfix-1.mjs** ```js // @simplewebauthn/server@"probably 14.0.3" import { generateRegistrationOptions } from '@simplewebauthn/server'; ``` ```sh $ node issue-807-postfix-1.mjs # No output ``` **issue-807-postfix-2.mjs** ```js // @simplewebauthn/server@"probably 14.0.3" import { generateRegistrationOptions } from '@simplewebauthn/server'; console.log('Calling generateRegistrationOptions()', await generateRegistrationOptions({})); ``` ``` $ node issue-807-postfix-1.mjs Calling generateRegistrationOptions() { # ... } (node:16489) ExperimentalWarning: The supports Web Crypto API method is an experimental feature and might change at any time (Use `node --trace-warnings ...` to show where the warning was created) (node:16489) ExperimentalWarning: The ML-DSA-44 Web Crypto API algorithm is an experimental feature and might change at any time ``` Fixes #807.
1 parent 7e3c4c4 commit cd402cc

3 files changed

Lines changed: 13 additions & 16 deletions

File tree

‎packages/server/src/registration/generateRegistrationOptions.ts‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,16 @@ const defaultAuthenticatorSelection: AuthenticatorSelectionCriteria = {
2828
};
2929

3030
/**
31-
* Use the most commonly-supported algorithms
32-
* See the following:
33-
* - https://www.iana.org/assignments/cose/cose.xhtml#algorithms
34-
* - https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-pubkeycredparams
31+
* Generate the default array of public key algorithms to offer during registration. Defaults to
32+
* the most commonly-supported algorithms of EdDSA, ES256, and RS256. When the runtime supports
33+
* PQC algorithms, ML-DSA-44 is included as the most preferred algorithm.
3534
*/
36-
export let defaultSupportedAlgorithmIDs: COSEALG[] = [
37-
COSEALG.EdDSA,
38-
COSEALG.ES256,
39-
COSEALG.RS256,
40-
];
35+
export function getDefaultSupportedAlgorithmIDs(): COSEALG[] {
36+
if (SettingsService.runtimeSupportsPQC()) {
37+
return [COSEALG.ML_DSA_44, COSEALG.EdDSA, COSEALG.ES256, COSEALG.RS256];
38+
}
4139

42-
if (SettingsService.runtimeSupportsPQC()) {
43-
defaultSupportedAlgorithmIDs = [COSEALG.ML_DSA_44, ...defaultSupportedAlgorithmIDs];
40+
return [COSEALG.EdDSA, COSEALG.ES256, COSEALG.RS256];
4441
}
4542

4643
/**
@@ -94,7 +91,7 @@ export async function generateRegistrationOptions(
9491
excludeCredentials = [],
9592
authenticatorSelection = defaultAuthenticatorSelection,
9693
extensions,
97-
supportedAlgorithmIDs = defaultSupportedAlgorithmIDs,
94+
supportedAlgorithmIDs = getDefaultSupportedAlgorithmIDs(),
9895
preferredAuthenticatorType,
9996
} = options;
10097

‎packages/server/src/registration/verifyRegistrationResponse.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { matchExpectedRPID } from '../helpers/matchExpectedRPID.ts';
2222
import { isoBase64URL } from '../helpers/iso/index.ts';
2323
import { SettingsService } from '../services/settingsService.ts';
2424

25-
import { defaultSupportedAlgorithmIDs } from './generateRegistrationOptions.ts';
25+
import { getDefaultSupportedAlgorithmIDs } from './generateRegistrationOptions.ts';
2626
import { verifyAttestationFIDOU2F } from './verifications/verifyAttestationFIDOU2F.ts';
2727
import { verifyAttestationPacked } from './verifications/verifyAttestationPacked.ts';
2828
import { verifyAttestationAndroidSafetyNet } from './verifications/verifyAttestationAndroidSafetyNet.ts';
@@ -71,7 +71,7 @@ export async function verifyRegistrationResponse(
7171
expectedType,
7272
requireUserPresence = true,
7373
requireUserVerification = true,
74-
supportedAlgorithmIDs = defaultSupportedAlgorithmIDs,
74+
supportedAlgorithmIDs = getDefaultSupportedAlgorithmIDs(),
7575
attestationSafetyNetEnforceCTSCheck = true,
7676
} = options;
7777
const { id, rawId, type: credentialType, response: attestationResponse } = response;

‎packages/server/src/services/settingsService.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ class BaseSettingsService implements SettingsService {
4343
// Certificates are stored as PEM-formatted strings
4444
private pemCertificates: Map<RootCertIdentifier, string[]>;
4545
// Track whether the runtime supports PQC algorithms
46-
private _runtimeSupportsPQC = false;
46+
private _runtimeSupportsPQC?: boolean;
4747

4848
constructor() {
4949
this.pemCertificates = new Map();
50-
this._runtimeSupportsPQC = runtimeSupportsWebCryptoKeyAlg('ML-DSA-44');
5150
}
5251

5352
setRootCertificates(opts: {
@@ -74,6 +73,7 @@ class BaseSettingsService implements SettingsService {
7473
}
7574

7675
runtimeSupportsPQC() {
76+
this._runtimeSupportsPQC ??= runtimeSupportsWebCryptoKeyAlg('ML-DSA-44');
7777
return this._runtimeSupportsPQC;
7878
}
7979
}

0 commit comments

Comments
 (0)