diff --git a/packages/server/src/registration/generateRegistrationOptions.ts b/packages/server/src/registration/generateRegistrationOptions.ts index a42d5a5d6..5ada91a0a 100644 --- a/packages/server/src/registration/generateRegistrationOptions.ts +++ b/packages/server/src/registration/generateRegistrationOptions.ts @@ -28,19 +28,16 @@ const defaultAuthenticatorSelection: AuthenticatorSelectionCriteria = { }; /** - * Use the most commonly-supported algorithms - * See the following: - * - https://www.iana.org/assignments/cose/cose.xhtml#algorithms - * - https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-pubkeycredparams + * Generate the default array of public key algorithms to offer during registration. Defaults to + * the most commonly-supported algorithms of EdDSA, ES256, and RS256. When the runtime supports + * PQC algorithms, ML-DSA-44 is included as the most preferred algorithm. */ -export let defaultSupportedAlgorithmIDs: COSEALG[] = [ - COSEALG.EdDSA, - COSEALG.ES256, - COSEALG.RS256, -]; +export function getDefaultSupportedAlgorithmIDs(): COSEALG[] { + if (SettingsService.runtimeSupportsPQC()) { + return [COSEALG.ML_DSA_44, COSEALG.EdDSA, COSEALG.ES256, COSEALG.RS256]; + } -if (SettingsService.runtimeSupportsPQC()) { - defaultSupportedAlgorithmIDs = [COSEALG.ML_DSA_44, ...defaultSupportedAlgorithmIDs]; + return [COSEALG.EdDSA, COSEALG.ES256, COSEALG.RS256]; } /** @@ -94,7 +91,7 @@ export async function generateRegistrationOptions( excludeCredentials = [], authenticatorSelection = defaultAuthenticatorSelection, extensions, - supportedAlgorithmIDs = defaultSupportedAlgorithmIDs, + supportedAlgorithmIDs = getDefaultSupportedAlgorithmIDs(), preferredAuthenticatorType, } = options; diff --git a/packages/server/src/registration/verifyRegistrationResponse.ts b/packages/server/src/registration/verifyRegistrationResponse.ts index b0bdc1bc4..242bfc583 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.ts @@ -22,7 +22,7 @@ import { matchExpectedRPID } from '../helpers/matchExpectedRPID.ts'; import { isoBase64URL } from '../helpers/iso/index.ts'; import { SettingsService } from '../services/settingsService.ts'; -import { defaultSupportedAlgorithmIDs } from './generateRegistrationOptions.ts'; +import { getDefaultSupportedAlgorithmIDs } from './generateRegistrationOptions.ts'; import { verifyAttestationFIDOU2F } from './verifications/verifyAttestationFIDOU2F.ts'; import { verifyAttestationPacked } from './verifications/verifyAttestationPacked.ts'; import { verifyAttestationAndroidSafetyNet } from './verifications/verifyAttestationAndroidSafetyNet.ts'; @@ -71,7 +71,7 @@ export async function verifyRegistrationResponse( expectedType, requireUserPresence = true, requireUserVerification = true, - supportedAlgorithmIDs = defaultSupportedAlgorithmIDs, + supportedAlgorithmIDs = getDefaultSupportedAlgorithmIDs(), attestationSafetyNetEnforceCTSCheck = true, } = options; const { id, rawId, type: credentialType, response: attestationResponse } = response; diff --git a/packages/server/src/services/settingsService.ts b/packages/server/src/services/settingsService.ts index b3ab85924..49d8431d1 100644 --- a/packages/server/src/services/settingsService.ts +++ b/packages/server/src/services/settingsService.ts @@ -43,11 +43,10 @@ class BaseSettingsService implements SettingsService { // Certificates are stored as PEM-formatted strings private pemCertificates: Map; // Track whether the runtime supports PQC algorithms - private _runtimeSupportsPQC = false; + private _runtimeSupportsPQC?: boolean; constructor() { this.pemCertificates = new Map(); - this._runtimeSupportsPQC = runtimeSupportsWebCryptoKeyAlg('ML-DSA-44'); } setRootCertificates(opts: { @@ -74,6 +73,7 @@ class BaseSettingsService implements SettingsService { } runtimeSupportsPQC() { + this._runtimeSupportsPQC ??= runtimeSupportsWebCryptoKeyAlg('ML-DSA-44'); return this._runtimeSupportsPQC; } }