summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Miller <matthew@millerti.me>2021-02-04 09:45:52 -0800
committerMatthew Miller <matthew@millerti.me>2021-02-04 09:45:52 -0800
commitc58ca6abf0d64a85771a865cf59f9783a20c66f0 (patch)
tree3f44297f5b47abf1b88db49ae11e399282a9adaf
parentd8cbcb40b9f32d7a6eab82f5e31c6e5272c9d163 (diff)
Restore userID argument in attestation options
-rw-r--r--packages/browser/src/helpers/toUint8Array.ts7
-rw-r--r--packages/browser/src/methods/startAttestation.test.ts5
-rw-r--r--packages/browser/src/methods/startAttestation.ts3
-rw-r--r--packages/server/src/attestation/generateAttestationOptions.ts9
-rw-r--r--packages/server/src/helpers/generateUserHandle.test.ts14
-rw-r--r--packages/server/src/helpers/generateUserHandle.ts16
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);
-}