diff options
author | Matthew Miller <matthew@millerti.me> | 2021-02-04 09:45:52 -0800 |
---|---|---|
committer | Matthew Miller <matthew@millerti.me> | 2021-02-04 09:45:52 -0800 |
commit | c58ca6abf0d64a85771a865cf59f9783a20c66f0 (patch) | |
tree | 3f44297f5b47abf1b88db49ae11e399282a9adaf | |
parent | d8cbcb40b9f32d7a6eab82f5e31c6e5272c9d163 (diff) |
Restore userID argument in attestation options
6 files changed, 16 insertions, 38 deletions
diff --git a/packages/browser/src/helpers/toUint8Array.ts b/packages/browser/src/helpers/toUint8Array.ts new file mode 100644 index 0000000..1e2243f --- /dev/null +++ b/packages/browser/src/helpers/toUint8Array.ts @@ -0,0 +1,7 @@ +/** + * A helper method to convert an arbitrary string sent from the server to a Uint8Array the + * authenticator will expect. + */ +export default function toUint8Array(value: string): Uint8Array { + return new TextEncoder().encode(value); +} diff --git a/packages/browser/src/methods/startAttestation.test.ts b/packages/browser/src/methods/startAttestation.test.ts index ad71488..d178609 100644 --- a/packages/browser/src/methods/startAttestation.test.ts +++ b/packages/browser/src/methods/startAttestation.test.ts @@ -3,6 +3,7 @@ import { PublicKeyCredentialCreationOptionsJSON, } from '@simplewebauthn/typescript-types'; +import toUint8Array from '../helpers/toUint8Array'; import supportsWebauthn from '../helpers/supportsWebauthn'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; @@ -17,7 +18,7 @@ const mockAttestationObject = 'mockAtte'; const mockClientDataJSON = 'mockClie'; const goodOpts1: PublicKeyCredentialCreationOptionsJSON = { - challenge: bufferToBase64URLString(Buffer.from('fizz', 'ascii')), + challenge: bufferToBase64URLString(toUint8Array('fizz')), attestation: 'direct', pubKeyCredParams: [ { @@ -87,7 +88,7 @@ test('should return base64url-encoded response values', async done => { return new Promise(resolve => { resolve({ id: 'foobar', - rawId: Buffer.from('foobar', 'ascii'), + rawId: toUint8Array('foobar'), response: { attestationObject: Buffer.from(mockAttestationObject, 'ascii'), clientDataJSON: Buffer.from(mockClientDataJSON, 'ascii'), diff --git a/packages/browser/src/methods/startAttestation.ts b/packages/browser/src/methods/startAttestation.ts index 9594bb9..0b2235d 100644 --- a/packages/browser/src/methods/startAttestation.ts +++ b/packages/browser/src/methods/startAttestation.ts @@ -4,6 +4,7 @@ import { AttestationCredentialJSON, } from '@simplewebauthn/typescript-types'; +import toUint8Array from '../helpers/toUint8Array'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import base64URLStringToBuffer from '../helpers/base64URLStringToBuffer'; import supportsWebauthn from '../helpers/supportsWebauthn'; @@ -27,7 +28,7 @@ export default async function startAttestation( challenge: base64URLStringToBuffer(creationOptionsJSON.challenge), user: { ...creationOptionsJSON.user, - id: base64URLStringToBuffer(creationOptionsJSON.user.id), + id: toUint8Array(creationOptionsJSON.user.id), }, excludeCredentials: creationOptionsJSON.excludeCredentials.map(toPublicKeyCredentialDescriptor), }; diff --git a/packages/server/src/attestation/generateAttestationOptions.ts b/packages/server/src/attestation/generateAttestationOptions.ts index 7d888d1..a523cd1 100644 --- a/packages/server/src/attestation/generateAttestationOptions.ts +++ b/packages/server/src/attestation/generateAttestationOptions.ts @@ -10,11 +10,11 @@ import type { import base64url from 'base64url'; import generateChallenge from '../helpers/generateChallenge'; -import generateUserHandle from '../helpers/generateUserHandle'; type Options = { rpName: string; rpID: string; + userID: string; userName: string; challenge?: string | Buffer; userDisplayName?: string; @@ -79,6 +79,7 @@ const defaultSupportedAlgorithmIDs = supportedCOSEAlgorithmIdentifiers.filter(id * * @param rpName User-visible, "friendly" website/service name * @param rpID Valid domain name (after `https://`) + * @param userID User's website-specific unique ID * @param userName User's website-specific username (email, etc...) * @param challenge Random value the authenticator needs to sign and pass back * @param userDisplayName User's actual name @@ -98,6 +99,7 @@ export default function generateAttestationOptions( const { rpName, rpID, + userID, userName, challenge = generateChallenge(), userDisplayName = userName, @@ -129,9 +131,6 @@ export default function generateAttestationOptions( authenticatorSelection.requireResidentKey = false; } - // Generate a new, random ID for better privacy - const userHandle = generateUserHandle(); - return { challenge: base64url.encode(challenge), rp: { @@ -139,7 +138,7 @@ export default function generateAttestationOptions( id: rpID, }, user: { - id: base64url.encode(userHandle), + id: userID, name: userName, displayName: userDisplayName, }, diff --git a/packages/server/src/helpers/generateUserHandle.test.ts b/packages/server/src/helpers/generateUserHandle.test.ts deleted file mode 100644 index 16ff898..0000000 --- a/packages/server/src/helpers/generateUserHandle.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import generateUserHandle from './generateUserHandle'; - -test('should return a buffer of 64 bytes', () => { - const userHandle = generateUserHandle(); - - expect(userHandle.byteLength).toBe(64); -}); - -test('should return random bytes on each execution', () => { - const challenge1 = generateUserHandle(); - const challenge2 = generateUserHandle(); - - expect(challenge1).not.toEqual(challenge2); -}); diff --git a/packages/server/src/helpers/generateUserHandle.ts b/packages/server/src/helpers/generateUserHandle.ts deleted file mode 100644 index be3f838..0000000 --- a/packages/server/src/helpers/generateUserHandle.ts +++ /dev/null @@ -1,16 +0,0 @@ -import crypto from 'crypto'; - -/** - * Generate a suitably random value to be used as a user handle when creating a credential - */ -export default function generateUserHandle(): Buffer { - /** - * As per WebAuthn spec: - * - * "A user handle is an opaque byte sequence with a maximum size of 64 bytes, and is not meant to - * be displayed to the user." - * - * See https://w3c.github.io/webauthn/#user-handle - */ - return crypto.randomBytes(64); -} |