Skip to content

Commit a567741

Browse files
authored
feat: Support AAGUID for PassKey devices (#3508)
<!-- Make sure you talk to us before submitting changes. See CONTRIBUTING.md. --> # Motivation Store AAGUID for passkey devices in order to remind users where a particular passkey is coming from. # Changes * Added API field AuthnMethod.aaguid. * Extended the Device layout to store 16 bytes per passkey `aaguid`. * Since `aaguid` is an optional filed (both in the API and storage), we benefit from Candid type compatibility. # Tests <!-- Please provide any information or screenshots about the tests that have been done --> <!-- SCREENSHOTS REPORT START --> <!-- SCREENSHOTS REPORT STOP -->
1 parent 1115f8a commit a567741

File tree

30 files changed

+550
-15
lines changed

30 files changed

+550
-15
lines changed

src/frontend/src/lib/flows/migrationFlow.svelte.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ export class MigrationFlow {
152152
new Uint8Array(passkeyIdentity.getPublicKey().toDer()),
153153
),
154154
credential_id: Array.from(new Uint8Array(credentialId)),
155+
aaguid: [],
155156
},
156157
},
157158
})

src/frontend/src/lib/generated/internet_identity_idl.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const idlFactory = ({ IDL }) => {
9797
'protection' : DeviceProtection,
9898
'pubkey' : DeviceKey,
9999
'key_type' : KeyType,
100+
'aaguid' : IDL.Opt(IDL.Vec(IDL.Nat8)),
100101
'purpose' : Purpose,
101102
'credential_id' : IDL.Opt(CredentialId),
102103
});
@@ -137,6 +138,7 @@ export const idlFactory = ({ IDL }) => {
137138
const PublicKeyAuthn = IDL.Record({ 'pubkey' : PublicKey });
138139
const WebAuthn = IDL.Record({
139140
'pubkey' : PublicKey,
141+
'aaguid' : IDL.Opt(IDL.Vec(IDL.Nat8)),
140142
'credential_id' : CredentialId,
141143
});
142144
const AuthnMethod = IDL.Variant({
@@ -273,6 +275,7 @@ export const idlFactory = ({ IDL }) => {
273275
'protection' : DeviceProtection,
274276
'pubkey' : DeviceKey,
275277
'key_type' : KeyType,
278+
'aaguid' : IDL.Opt(IDL.Vec(IDL.Nat8)),
276279
'purpose' : Purpose,
277280
'credential_id' : IDL.Opt(CredentialId),
278281
});

src/frontend/src/lib/generated/internet_identity_types.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ export interface DeviceData {
347347
'protection' : DeviceProtection,
348348
'pubkey' : DeviceKey,
349349
'key_type' : KeyType,
350+
'aaguid' : [] | [Uint8Array | number[]],
350351
'purpose' : Purpose,
351352
'credential_id' : [] | [CredentialId],
352353
}
@@ -394,6 +395,7 @@ export interface DeviceWithUsage {
394395
'protection' : DeviceProtection,
395396
'pubkey' : DeviceKey,
396397
'key_type' : KeyType,
398+
'aaguid' : [] | [Uint8Array | number[]],
397399
'purpose' : Purpose,
398400
'credential_id' : [] | [CredentialId],
399401
}
@@ -952,6 +954,10 @@ export type VerifyTentativeDeviceResponse = {
952954
*/
953955
export interface WebAuthn {
954956
'pubkey' : PublicKey,
957+
/**
958+
* Authenticator Attestation Global Unique Identifier (AAGUID)
959+
*/
960+
'aaguid' : [] | [Uint8Array | number[]],
955961
'credential_id' : CredentialId,
956962
}
957963
export interface WebAuthnCredential {

src/frontend/src/lib/legacy/flows/addDevice/welcomeView/registerTentativeDevice.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export const registerTentativeDevice = async (
9292
),
9393
purpose: { authentication: null },
9494
credential_id: [Array.from(new Uint8Array(result.rawId))],
95+
aaguid: [],
9596
metadata: [],
9697
};
9798
const addResponse = await addTentativeDevice({

src/frontend/src/lib/legacy/flows/manage/devicesFromDevicesWithUsage.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ describe("devicesFromDevicesWithUsage", () => {
3939
key_type: { platform: null },
4040
purpose: { authentication: null },
4141
credential_id: [],
42+
aaguid: [],
4243
});
4344

4445
describe("domains compatibility flag disabled", () => {

src/frontend/src/lib/legacy/flows/manage/migration.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const recoveryPhrase: DeviceData = {
1111
key_type: { seed_phrase: null },
1212
purpose: { recovery: null },
1313
credential_id: [],
14+
aaguid: [],
1415
metadata: [],
1516
};
1617

@@ -23,6 +24,7 @@ const authenticator: DeviceData = {
2324
key_type: { unknown: null },
2425
purpose: { authentication: null },
2526
credential_id: [],
27+
aaguid: [],
2628
metadata: [],
2729
};
2830

src/frontend/src/lib/legacy/flows/recovery/recoveryWizard.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const recoveryPhrase: Omit<DeviceData, "alias"> = {
2020
key_type: { seed_phrase: null },
2121
purpose: { recovery: null },
2222
credential_id: [],
23+
aaguid: [],
2324
metadata: [],
2425
};
2526

@@ -31,6 +32,7 @@ const device: Omit<DeviceData, "alias"> = {
3132
key_type: { unknown: null },
3233
purpose: { authentication: null },
3334
credential_id: [],
35+
aaguid: [],
3436
metadata: [],
3537
};
3638

@@ -42,6 +44,7 @@ const recoveryDevice: Omit<DeviceData, "alias"> = {
4244
key_type: { cross_platform: null },
4345
purpose: { recovery: null },
4446
credential_id: [Uint8Array.from([0, 0, 0, 0, 0])],
47+
aaguid: [],
4548
};
4649

4750
const oneDeviceOnly: Omit<DeviceData, "alias">[] = [device];

src/frontend/src/lib/utils/accessMethods.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ const makeAuthnMethodWithOrigin = (origin?: string): AuthnMethodData => {
6767
},
6868
metadata,
6969
authn_method: {
70-
WebAuthn: { pubkey: new Uint8Array(), credential_id: new Uint8Array() },
70+
WebAuthn: {
71+
pubkey: new Uint8Array(),
72+
credential_id: new Uint8Array(),
73+
aaguid: [],
74+
},
7175
},
7276
} as AuthnMethodData;
7377
};
@@ -260,7 +264,11 @@ describe("getOrigin", () => {
260264
},
261265
metadata: [],
262266
authn_method: {
263-
WebAuthn: { pubkey: new Uint8Array(), credential_id: new Uint8Array() },
267+
WebAuthn: {
268+
pubkey: new Uint8Array(),
269+
credential_id: new Uint8Array(),
270+
aaguid: [],
271+
},
264272
},
265273
} as AuthnMethodData;
266274
expect(getOrigin(method)).toBeUndefined();
@@ -276,7 +284,11 @@ describe("getOrigin", () => {
276284
},
277285
metadata: [["origin", { Bytes: [1, 2, 3] }]],
278286
authn_method: {
279-
WebAuthn: { pubkey: new Uint8Array(), credential_id: new Uint8Array() },
287+
WebAuthn: {
288+
pubkey: new Uint8Array(),
289+
credential_id: new Uint8Array(),
290+
aaguid: [],
291+
},
280292
},
281293
} as AuthnMethodData;
282294
expect(getOrigin(method)).toBeUndefined();
@@ -362,7 +374,11 @@ describe("isLegacyAuthnMethod", () => {
362374
},
363375
metadata,
364376
authn_method: {
365-
WebAuthn: { pubkey: new Uint8Array(), credential_id: new Uint8Array() },
377+
WebAuthn: {
378+
pubkey: new Uint8Array(),
379+
credential_id: new Uint8Array(),
380+
aaguid: [],
381+
},
366382
},
367383
} as AuthnMethodData;
368384
};
@@ -477,6 +493,7 @@ describe("isSameAccessMethod", () => {
477493
WebAuthn: {
478494
pubkey: new Uint8Array(pubkeyBytes),
479495
credential_id: new Uint8Array([1, 2, 3]),
496+
aaguid: [],
480497
},
481498
},
482499
} as AuthnMethodData;

src/frontend/src/lib/utils/authnMethodData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export const passkeyAuthnMethodData = ({
6969
WebAuthn: {
7070
pubkey: new Uint8Array(pubKey),
7171
credential_id: new Uint8Array(credentialId),
72+
aaguid: [],
7273
},
7374
},
7475
security_settings: defaultSecuritySettings(),

src/frontend/src/lib/utils/credential-devices.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ describe("credetial-devices test", () => {
1313
key_type: { unknown: null },
1414
purpose: { authentication: null },
1515
credential_id: [],
16+
aaguid: [],
1617
metadata: [],
1718
});
1819

0 commit comments

Comments
 (0)