From b5a07a29efa40d93d6abcc70c337be587d5835bb Mon Sep 17 00:00:00 2001 From: Mike Beaumont Date: Sat, 19 Sep 2026 18:41:53 +0200 Subject: [PATCH] feat: include passkey icons based on AAGUID (#1756) --- .github/workflows/update-aaguids.yml | 16 +- backend/internal/dto/webauthn_dto.go | 3 + backend/internal/dto/webauthn_dto_test.go | 55 + backend/internal/model/webauthn.go | 8 + backend/internal/utils/aaguid_util.go | 94 +- backend/internal/utils/aaguid_util_test.go | 144 +- backend/internal/webauthn/handler.go | 27 + backend/internal/webauthn/module.go | 2 + backend/internal/webauthn/service.go | 2 + backend/internal/webauthn/service_test.go | 34 + .../aaguid-icons/0279c1253367b259.svg | 5 + .../aaguid-icons/0e2f0531497ba5d8.svg | 23 + .../aaguid-icons/1daa712dea9ae46e.svg | 15 + .../aaguid-icons/20285b58ca2ca438.svg | 1 + .../aaguid-icons/22fc41ef278b65de.svg | 3 + .../aaguid-icons/2c4bbc32e0601d9a.svg | 1 + .../aaguid-icons/2d20b2b69c1bdff8.svg | 3 + .../aaguid-icons/3256d3e03d87ce0a.svg | 34 + .../aaguid-icons/33d59618e594bb49.svg | 81 ++ .../aaguid-icons/382fbdca2eb19cec.svg | 11 + .../aaguid-icons/392d7b1382ef234c.svg | 5 + .../aaguid-icons/3931ecb62e3b6f2a.svg | 76 + .../aaguid-icons/3c30e5f535168e89.svg | 3 + .../aaguid-icons/3ddddea0f68ee3b1.svg | 4 + .../aaguid-icons/46ac2bd17caa6d0b.svg | 1 + .../aaguid-icons/5301484de70d13e2.svg | 99 ++ .../aaguid-icons/53eaed3308753caf.svg | 25 + .../aaguid-icons/54c30775685066bc.svg | 18 + .../aaguid-icons/55ed42788d41383d.svg | 3 + .../aaguid-icons/56f8d0a7f2afba25.svg | 1 + .../aaguid-icons/5bca10e7f5aebe1d.svg | 12 + .../aaguid-icons/5cacab8124984715.svg | 1 + .../aaguid-icons/5f7a884ad381ceaa.svg | 1 + .../aaguid-icons/62ef07f809c7f588.svg | 1 + .../aaguid-icons/72a52980cf2b1ed9.svg | 46 + .../aaguid-icons/75a96840f046f6f0.svg | 1 + .../aaguid-icons/7b0a06b33cb3cd3f.svg | 63 + .../aaguid-icons/7b4f712b63784561.svg | 7 + .../aaguid-icons/7d860a7c62be8a03.svg | 13 + .../aaguid-icons/7db3534fd5258565.svg | 1 + .../aaguid-icons/7f0646d4fff1e946.svg | 1 + .../aaguid-icons/7fd2cfb58273936e.svg | 17 + .../aaguid-icons/80ced24b0dc2e7bf.svg | 23 + .../aaguid-icons/851ebd6098a28f3a.svg | 4 + .../aaguid-icons/8bae707e5f61c50a.svg | 1 + .../aaguid-icons/8f3d2a109e86bfc7.svg | 17 + .../aaguid-icons/8f995c717fd11cf3.svg | 13 + .../aaguid-icons/905e0b26ed90f80c.svg | 8 + .../aaguid-icons/986d1b758c1c0666.svg | 1 + .../aaguid-icons/9b8cfdb7d699e942.svg | 12 + .../aaguid-icons/9d2487ab5b1de66c.svg | 38 + .../aaguid-icons/9f46d84e118605ca.svg | 1 + .../aaguid-icons/a22945d6b8b2c855.svg | 91 ++ .../aaguid-icons/a2983af5687c5c09.svg | 36 + .../aaguid-icons/a547d13b2f7bee29.svg | 3 + .../aaguid-icons/a5a686d92796b3ff.svg | 1 + .../aaguid-icons/a72a9761e0b6dd4b.svg | 1 + .../aaguid-icons/a8a6898e204a3630.svg | 17 + .../aaguid-icons/a9773b88cb8d368a.svg | 8 + .../aaguid-icons/b8c6b04b104706c9.svg | 27 + .../aaguid-icons/b8db2a5d142953ed.svg | 12 + .../aaguid-icons/b9815d4fd9eb10a7.svg | 8 + .../aaguid-icons/c1cfd304e92622af.svg | 12 + .../aaguid-icons/c7b0f8dd95f195cf.svg | 8 + .../aaguid-icons/c8448a372019a31d.svg | 3 + .../aaguid-icons/c98f30b9093e282e.svg | 3 + .../aaguid-icons/cbc4ebc69a8d3188.svg | 3 + .../aaguid-icons/cc62b8c5575a65ae.svg | 11 + .../aaguid-icons/d09754c3034c4d86.svg | 55 + .../aaguid-icons/d6098dee8bf5800c.svg | 1 + .../aaguid-icons/db8f0d82e2ffc1a4.svg | 14 + .../aaguid-icons/e5f7c847e7bb1823.svg | 1 + .../aaguid-icons/e63a433d41e3bbd1.svg | 1 + .../aaguid-icons/e8ae0a4206de8b1f.svg | 21 + .../aaguid-icons/faac7e28bcf9ba73.svg | 8 + .../aaguid-icons/fe2583b9176a3347.svg | 1 + backend/resources/aaguids.json | 1294 ++++++++++++++++- backend/resources/files.go | 2 +- ...16120000_webauthn_credential_icon.down.sql | 1 + ...0916120000_webauthn_credential_icon.up.sql | 1 + ...16120000_webauthn_credential_icon.down.sql | 1 + ...0916120000_webauthn_credential_icon.up.sql | 1 + .../src/lib/components/passkey-row.svelte | 26 +- frontend/src/lib/types/passkey.type.ts | 2 + frontend/src/lib/utils/cached-image-util.ts | 11 + .../lib/utils/unsaved-changes-util.svelte.ts | 2 +- .../settings/account/passkey-list.svelte | 7 + .../users/[id]/admin-passkey-list.svelte | 7 + scripts/update-aaguids.go | 198 +++ tests/specs/cli.spec.ts | 5 + 90 files changed, 2934 insertions(+), 49 deletions(-) create mode 100644 backend/internal/dto/webauthn_dto_test.go create mode 100644 backend/resources/aaguid-icons/0279c1253367b259.svg create mode 100644 backend/resources/aaguid-icons/0e2f0531497ba5d8.svg create mode 100644 backend/resources/aaguid-icons/1daa712dea9ae46e.svg create mode 100644 backend/resources/aaguid-icons/20285b58ca2ca438.svg create mode 100644 backend/resources/aaguid-icons/22fc41ef278b65de.svg create mode 100644 backend/resources/aaguid-icons/2c4bbc32e0601d9a.svg create mode 100644 backend/resources/aaguid-icons/2d20b2b69c1bdff8.svg create mode 100644 backend/resources/aaguid-icons/3256d3e03d87ce0a.svg create mode 100644 backend/resources/aaguid-icons/33d59618e594bb49.svg create mode 100644 backend/resources/aaguid-icons/382fbdca2eb19cec.svg create mode 100644 backend/resources/aaguid-icons/392d7b1382ef234c.svg create mode 100644 backend/resources/aaguid-icons/3931ecb62e3b6f2a.svg create mode 100644 backend/resources/aaguid-icons/3c30e5f535168e89.svg create mode 100644 backend/resources/aaguid-icons/3ddddea0f68ee3b1.svg create mode 100644 backend/resources/aaguid-icons/46ac2bd17caa6d0b.svg create mode 100644 backend/resources/aaguid-icons/5301484de70d13e2.svg create mode 100644 backend/resources/aaguid-icons/53eaed3308753caf.svg create mode 100644 backend/resources/aaguid-icons/54c30775685066bc.svg create mode 100644 backend/resources/aaguid-icons/55ed42788d41383d.svg create mode 100644 backend/resources/aaguid-icons/56f8d0a7f2afba25.svg create mode 100644 backend/resources/aaguid-icons/5bca10e7f5aebe1d.svg create mode 100644 backend/resources/aaguid-icons/5cacab8124984715.svg create mode 100644 backend/resources/aaguid-icons/5f7a884ad381ceaa.svg create mode 100644 backend/resources/aaguid-icons/62ef07f809c7f588.svg create mode 100644 backend/resources/aaguid-icons/72a52980cf2b1ed9.svg create mode 100644 backend/resources/aaguid-icons/75a96840f046f6f0.svg create mode 100644 backend/resources/aaguid-icons/7b0a06b33cb3cd3f.svg create mode 100644 backend/resources/aaguid-icons/7b4f712b63784561.svg create mode 100644 backend/resources/aaguid-icons/7d860a7c62be8a03.svg create mode 100644 backend/resources/aaguid-icons/7db3534fd5258565.svg create mode 100644 backend/resources/aaguid-icons/7f0646d4fff1e946.svg create mode 100644 backend/resources/aaguid-icons/7fd2cfb58273936e.svg create mode 100644 backend/resources/aaguid-icons/80ced24b0dc2e7bf.svg create mode 100644 backend/resources/aaguid-icons/851ebd6098a28f3a.svg create mode 100644 backend/resources/aaguid-icons/8bae707e5f61c50a.svg create mode 100644 backend/resources/aaguid-icons/8f3d2a109e86bfc7.svg create mode 100644 backend/resources/aaguid-icons/8f995c717fd11cf3.svg create mode 100644 backend/resources/aaguid-icons/905e0b26ed90f80c.svg create mode 100644 backend/resources/aaguid-icons/986d1b758c1c0666.svg create mode 100644 backend/resources/aaguid-icons/9b8cfdb7d699e942.svg create mode 100644 backend/resources/aaguid-icons/9d2487ab5b1de66c.svg create mode 100644 backend/resources/aaguid-icons/9f46d84e118605ca.svg create mode 100644 backend/resources/aaguid-icons/a22945d6b8b2c855.svg create mode 100644 backend/resources/aaguid-icons/a2983af5687c5c09.svg create mode 100644 backend/resources/aaguid-icons/a547d13b2f7bee29.svg create mode 100644 backend/resources/aaguid-icons/a5a686d92796b3ff.svg create mode 100644 backend/resources/aaguid-icons/a72a9761e0b6dd4b.svg create mode 100644 backend/resources/aaguid-icons/a8a6898e204a3630.svg create mode 100644 backend/resources/aaguid-icons/a9773b88cb8d368a.svg create mode 100644 backend/resources/aaguid-icons/b8c6b04b104706c9.svg create mode 100644 backend/resources/aaguid-icons/b8db2a5d142953ed.svg create mode 100644 backend/resources/aaguid-icons/b9815d4fd9eb10a7.svg create mode 100644 backend/resources/aaguid-icons/c1cfd304e92622af.svg create mode 100644 backend/resources/aaguid-icons/c7b0f8dd95f195cf.svg create mode 100644 backend/resources/aaguid-icons/c8448a372019a31d.svg create mode 100644 backend/resources/aaguid-icons/c98f30b9093e282e.svg create mode 100644 backend/resources/aaguid-icons/cbc4ebc69a8d3188.svg create mode 100644 backend/resources/aaguid-icons/cc62b8c5575a65ae.svg create mode 100644 backend/resources/aaguid-icons/d09754c3034c4d86.svg create mode 100644 backend/resources/aaguid-icons/d6098dee8bf5800c.svg create mode 100644 backend/resources/aaguid-icons/db8f0d82e2ffc1a4.svg create mode 100644 backend/resources/aaguid-icons/e5f7c847e7bb1823.svg create mode 100644 backend/resources/aaguid-icons/e63a433d41e3bbd1.svg create mode 100644 backend/resources/aaguid-icons/e8ae0a4206de8b1f.svg create mode 100644 backend/resources/aaguid-icons/faac7e28bcf9ba73.svg create mode 100644 backend/resources/aaguid-icons/fe2583b9176a3347.svg create mode 100644 backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.down.sql create mode 100644 backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.up.sql create mode 100644 backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.down.sql create mode 100644 backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.up.sql create mode 100644 scripts/update-aaguids.go diff --git a/.github/workflows/update-aaguids.yml b/.github/workflows/update-aaguids.yml index 871b00d2..4c0957ba 100644 --- a/.github/workflows/update-aaguids.yml +++ b/.github/workflows/update-aaguids.yml @@ -17,15 +17,13 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - - name: Fetch JSON data - run: | - curl -o data.json https://raw.githubusercontent.com/pocket-id/passkey-aaguids/refs/heads/main/combined_aaguid.json + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: stable - - name: Process JSON data - run: | - mkdir -p backend/resources - jq -c 'map_values(.name)' data.json > backend/resources/aaguids.json - rm data.json + - name: Update AAGUIDs and authenticator icons + run: go run scripts/update-aaguids.go - name: Create Pull Request uses: peter-evans/create-pull-request@v7 @@ -33,7 +31,7 @@ jobs: commit-message: "chore: update AAGUIDs" title: "chore: update AAGUIDs" body: | - This PR updates the AAGUIDs file with the latest data from the [passkey-aaguids](https://github.com/pocket-id/passkey-aaguids) repository. + This PR updates the AAGUID metadata and authenticator icons with the latest data from the [passkey-aaguids](https://github.com/pocket-id/passkey-aaguids) repository. branch: update-aaguids base: main delete-branch: true diff --git a/backend/internal/dto/webauthn_dto.go b/backend/internal/dto/webauthn_dto.go index e1383f92..a3d1ef9b 100644 --- a/backend/internal/dto/webauthn_dto.go +++ b/backend/internal/dto/webauthn_dto.go @@ -15,6 +15,9 @@ type WebauthnCredentialDto struct { BackupEligible bool `json:"backupEligible"` BackupState bool `json:"backupState"` + AAGUID string `json:"aaguid"` + HasIcon bool `json:"hasIcon"` + CreatedAt datatype.DateTime `json:"createdAt"` } diff --git a/backend/internal/dto/webauthn_dto_test.go b/backend/internal/dto/webauthn_dto_test.go new file mode 100644 index 00000000..b73625e8 --- /dev/null +++ b/backend/internal/dto/webauthn_dto_test.go @@ -0,0 +1,55 @@ +package dto + +import ( + "encoding/json" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/pocket-id/pocket-id/backend/internal/model" + "github.com/pocket-id/pocket-id/backend/internal/utils" +) + +func TestWebauthnCredentialDto_iconFields(t *testing.T) { + withIcon := anyAAGUIDWithIcon(t) + + credentials := []model.WebauthnCredential{ + {Name: "With icon", AAGUID: withIcon}, + {Name: "Unknown authenticator", AAGUID: "ffffffff-ffff-ffff-ffff-ffffffffffff"}, + {Name: "Authenticator that does not identify itself", AAGUID: utils.ZeroAAGUID}, + } + + var dtos []WebauthnCredentialDto + require.NoError(t, MapStructList(credentials, &dtos)) + require.Len(t, dtos, len(credentials)) + + require.Equal(t, withIcon, dtos[0].AAGUID) + require.True(t, dtos[0].HasIcon) + + require.False(t, dtos[1].HasIcon) + + require.Equal(t, utils.ZeroAAGUID, dtos[2].AAGUID) + require.False(t, dtos[2].HasIcon) +} + +func anyAAGUIDWithIcon(t *testing.T) string { + t.Helper() + + data, err := os.ReadFile("../../resources/aaguids.json") + require.NoError(t, err) + + var metadata map[string]struct { + IconLight string `json:"icon_light"` + } + require.NoError(t, json.Unmarshal(data, &metadata)) + + for aaguid, entry := range metadata { + if entry.IconLight != "" && utils.HasAuthenticatorIcon(aaguid) { + return aaguid + } + } + + t.Skip("no authenticator icons are embedded") + return "" +} diff --git a/backend/internal/model/webauthn.go b/backend/internal/model/webauthn.go index ee44147e..e3dc2929 100644 --- a/backend/internal/model/webauthn.go +++ b/backend/internal/model/webauthn.go @@ -20,9 +20,17 @@ type WebauthnCredential struct { BackupEligible bool `json:"backupEligible"` BackupState bool `json:"backupState"` + AAGUID string `gorm:"column:aaguid;default:00000000-0000-0000-0000-000000000000"` + UserID string } +// HasIcon reports whether an icon is embedded for this credential's authenticator +// It is mapped onto the DTO so the frontend knows upfront whether an icon is worth requesting +func (c WebauthnCredential) HasIcon() bool { + return utils.HasAuthenticatorIcon(c.AAGUID) +} + type AuthenticatorTransportList []protocol.AuthenticatorTransport //nolint:recvcheck // Scan and Value methods for GORM to handle the custom type diff --git a/backend/internal/utils/aaguid_util.go b/backend/internal/utils/aaguid_util.go index 2c25bf24..d01de82a 100644 --- a/backend/internal/utils/aaguid_util.go +++ b/backend/internal/utils/aaguid_util.go @@ -4,19 +4,39 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io/fs" "log/slog" + "os" + "path" "sync" + "uuid" "github.com/pocket-id/pocket-id/backend/resources" ) -var ( - aaguidMap map[string]string - aaguidMapOnce *sync.Once +const ( + aaguidIconsDir = "aaguid-icons" + authenticatorIconHashBytes = 8 ) +// ZeroAAGUID is the AAGUID reported by authenticators that do not want to identify themselves, and it is also the column default for credentials that were registered before AAGUIDs were tracked +var ZeroAAGUID = uuid.Nil().String() + +var ( + aaguidMetadata map[string]authenticatorMetadata + aaguidMetadataOnce *sync.Once +) + +// authenticatorMetadata records the display name and content-addressed icon files for an AAGUID +// IconDark is empty when the authenticator uses its light icon in both themes +type authenticatorMetadata struct { + Name string `json:"name"` + IconLight string `json:"icon_light"` + IconDark string `json:"icon_dark"` +} + func init() { - aaguidMapOnce = &sync.Once{} + aaguidMetadataOnce = &sync.Once{} } // FormatAAGUID converts an AAGUID byte slice to UUID string format @@ -42,18 +62,18 @@ func GetAuthenticatorName(aaguid []byte) string { return "" } - // Then check JSON-sourced map - aaguidMapOnce.Do(loadAAGUIDsFromFile) + // Then check the embedded metadata manifest + aaguidMetadataOnce.Do(loadAAGUIDMetadataFromFile) - if name, ok := aaguidMap[aaguidStr]; ok { - return name + " Passkey" + if metadata, ok := aaguidMetadata[aaguidStr]; ok && metadata.Name != "" { + return metadata.Name + " Passkey" } return "" } -// loadAAGUIDsFromFile loads AAGUID data from the embedded file system -func loadAAGUIDsFromFile() { +// loadAAGUIDMetadataFromFile loads AAGUID names and icon references from the embedded manifest +func loadAAGUIDMetadataFromFile() { // Read from embedded file system data, err := resources.FS.ReadFile("aaguids.json") if err != nil { @@ -61,9 +81,61 @@ func loadAAGUIDsFromFile() { return } - err = json.Unmarshal(data, &aaguidMap) + err = json.Unmarshal(data, &aaguidMetadata) if err != nil { slog.Error("Error unmarshalling AAGUID data", slog.Any("error", err)) return } } + +// HasAuthenticatorIcon reports whether an icon is embedded for the given AAGUID +// Callers use this to avoid pointing clients at an icon endpoint that would only answer with a 404 +func HasAuthenticatorIcon(aaguid string) bool { + aaguidMetadataOnce.Do(loadAAGUIDMetadataFromFile) + + metadata, ok := aaguidMetadata[aaguid] + return ok && validAuthenticatorIconName(metadata.IconLight) +} + +// OpenAuthenticatorIcon opens the embedded icon for the given AAGUID and returns it together with its size +// It returns os.ErrNotExist for every AAGUID without an icon, which is also what keeps caller-controlled input from ever reaching the embedded file system +func OpenAuthenticatorIcon(aaguid string, light bool) (fs.File, int64, error) { + aaguidMetadataOnce.Do(loadAAGUIDMetadataFromFile) + + // Only AAGUIDs with a valid generated light reference are served, so caller input never becomes an embedded file path + metadata, ok := aaguidMetadata[aaguid] + if !ok || !validAuthenticatorIconName(metadata.IconLight) { + return nil, 0, os.ErrNotExist + } + + // Fall back to the light icon when the authenticator does not ship a dark variant + name := metadata.IconLight + if !light && validAuthenticatorIconName(metadata.IconDark) { + name = metadata.IconDark + } + + file, err := resources.FS.Open(path.Join(aaguidIconsDir, name)) + if err != nil { + return nil, 0, err + } + + // The size is resolved upfront so the caller can stream the icon with a Content-Length instead of buffering it + stat, err := file.Stat() + if err != nil { + _ = file.Close() + return nil, 0, err + } + + return file, stat.Size(), nil +} + +// validAuthenticatorIconName accepts only the truncated SHA-256 file names emitted by the updater +func validAuthenticatorIconName(name string) bool { + const extension = ".svg" + if len(name) != authenticatorIconHashBytes*2+len(extension) || name[len(name)-len(extension):] != extension { + return false + } + + _, err := hex.DecodeString(name[:authenticatorIconHashBytes*2]) + return err == nil +} diff --git a/backend/internal/utils/aaguid_util_test.go b/backend/internal/utils/aaguid_util_test.go index f4a6ee13..e1576f6a 100644 --- a/backend/internal/utils/aaguid_util_test.go +++ b/backend/internal/utils/aaguid_util_test.go @@ -1,9 +1,18 @@ package utils import ( + "crypto/sha256" "encoding/hex" + "fmt" + "io" + "os" + "path" "sync" "testing" + + "github.com/stretchr/testify/require" + + "github.com/pocket-id/pocket-id/backend/resources" ) func TestFormatAAGUID(t *testing.T) { @@ -45,21 +54,21 @@ func TestFormatAAGUID(t *testing.T) { } func TestGetAuthenticatorName(t *testing.T) { - // Reset the aaguidMap for testing - originalMap := aaguidMap - originalOnce := aaguidMapOnce + // Preserve the package-level metadata cache so this test does not affect other tests + originalMetadata := aaguidMetadata + originalOnce := aaguidMetadataOnce defer func() { - aaguidMap = originalMap - aaguidMapOnce = originalOnce + aaguidMetadata = originalMetadata + aaguidMetadataOnce = originalOnce }() - // Inject a test AAGUID map - aaguidMap = map[string]string{ - "adce0002-35bc-c60a-648b-0b25f1f05503": "Test Authenticator", - "00000000-0000-0000-0000-000000000000": "Zero Authenticator", + // Inject test metadata without loading the embedded manifest + aaguidMetadata = map[string]authenticatorMetadata{ + "adce0002-35bc-c60a-648b-0b25f1f05503": {Name: "Test Authenticator"}, + "00000000-0000-0000-0000-000000000000": {Name: "Zero Authenticator"}, } - aaguidMapOnce = &sync.Once{} - aaguidMapOnce.Do(func() {}) // Mark as done to avoid loading from file + aaguidMetadataOnce = &sync.Once{} + aaguidMetadataOnce.Do(func() {}) tests := []struct { name string @@ -98,25 +107,22 @@ func TestGetAuthenticatorName(t *testing.T) { } } -func TestLoadAAGUIDsFromFile(t *testing.T) { - // Reset the map and once flag for clean testing - aaguidMap = nil - aaguidMapOnce = &sync.Once{} +func TestLoadAAGUIDMetadataFromFile(t *testing.T) { + // Reset the metadata cache so this test exercises the embedded manifest + aaguidMetadata = nil + aaguidMetadataOnce = &sync.Once{} - // Trigger loading of AAGUIDs by calling GetAuthenticatorName + // Trigger loading by resolving an arbitrary AAGUID GetAuthenticatorName([]byte{0x01, 0x02, 0x03, 0x04}) - if len(aaguidMap) == 0 { - t.Error("loadAAGUIDsFromFile() failed to populate aaguidMap") + if len(aaguidMetadata) == 0 { + t.Error("loadAAGUIDMetadataFromFile() failed to populate aaguidMetadata") } - // Check for a few known entries that should be in the embedded file - // This test will be more brittle as it depends on the content of aaguids.json, - // but it helps verify that the loading actually worked - t.Log("AAGUID map loaded with", len(aaguidMap), "entries") + t.Log("AAGUID metadata loaded with", len(aaguidMetadata), "entries") } -// Helper function to convert hex string to bytes +// mustDecodeHex keeps the table fixtures readable func mustDecodeHex(s string) []byte { bytes, err := hex.DecodeString(s) if err != nil { @@ -124,3 +130,95 @@ func mustDecodeHex(s string) []byte { } return bytes } + +func TestAuthenticatorIcons(t *testing.T) { + aaguidMetadataOnce.Do(loadAAGUIDMetadataFromFile) + if len(aaguidMetadata) == 0 { + t.Skip("no authenticator icons are embedded") + } + + var withDark, withoutDark string + referencedIcons := make(map[string]struct{}) + for aaguid, metadata := range aaguidMetadata { + if metadata.IconLight == "" { + continue + } + + require.True(t, validAuthenticatorIconName(metadata.IconLight), "icon %q has an invalid light reference", aaguid) + referencedIcons[metadata.IconLight] = struct{}{} + + if metadata.IconDark != "" { + require.True(t, validAuthenticatorIconName(metadata.IconDark), "icon %q has an invalid dark reference", aaguid) + referencedIcons[metadata.IconDark] = struct{}{} + } + + if metadata.IconDark != "" && withDark == "" { + withDark = aaguid + } + if metadata.IconDark == "" && withoutDark == "" { + withoutDark = aaguid + } + } + require.NotEmpty(t, withDark, "expected at least one authenticator with a separate dark icon") + require.NotEmpty(t, withoutDark, "expected at least one authenticator with a single icon") + + readIcon := func(t *testing.T, aaguid string, light bool) []byte { + t.Helper() + + file, size, err := OpenAuthenticatorIcon(aaguid, light) + require.NoError(t, err) + defer file.Close() + + data, err := io.ReadAll(file) + require.NoError(t, err) + require.Len(t, data, int(size)) + require.Contains(t, string(data), " + + + + diff --git a/backend/resources/aaguid-icons/0e2f0531497ba5d8.svg b/backend/resources/aaguid-icons/0e2f0531497ba5d8.svg new file mode 100644 index 00000000..c6ea793a --- /dev/null +++ b/backend/resources/aaguid-icons/0e2f0531497ba5d8.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/1daa712dea9ae46e.svg b/backend/resources/aaguid-icons/1daa712dea9ae46e.svg new file mode 100644 index 00000000..9d7f9d8e --- /dev/null +++ b/backend/resources/aaguid-icons/1daa712dea9ae46e.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/20285b58ca2ca438.svg b/backend/resources/aaguid-icons/20285b58ca2ca438.svg new file mode 100644 index 00000000..80a12953 --- /dev/null +++ b/backend/resources/aaguid-icons/20285b58ca2ca438.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/22fc41ef278b65de.svg b/backend/resources/aaguid-icons/22fc41ef278b65de.svg new file mode 100644 index 00000000..be61a5d4 --- /dev/null +++ b/backend/resources/aaguid-icons/22fc41ef278b65de.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/2c4bbc32e0601d9a.svg b/backend/resources/aaguid-icons/2c4bbc32e0601d9a.svg new file mode 100644 index 00000000..db821819 --- /dev/null +++ b/backend/resources/aaguid-icons/2c4bbc32e0601d9a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/2d20b2b69c1bdff8.svg b/backend/resources/aaguid-icons/2d20b2b69c1bdff8.svg new file mode 100644 index 00000000..dce77b77 --- /dev/null +++ b/backend/resources/aaguid-icons/2d20b2b69c1bdff8.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/3256d3e03d87ce0a.svg b/backend/resources/aaguid-icons/3256d3e03d87ce0a.svg new file mode 100644 index 00000000..5cbcc5d4 --- /dev/null +++ b/backend/resources/aaguid-icons/3256d3e03d87ce0a.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/33d59618e594bb49.svg b/backend/resources/aaguid-icons/33d59618e594bb49.svg new file mode 100644 index 00000000..aa454767 --- /dev/null +++ b/backend/resources/aaguid-icons/33d59618e594bb49.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/382fbdca2eb19cec.svg b/backend/resources/aaguid-icons/382fbdca2eb19cec.svg new file mode 100644 index 00000000..55424277 --- /dev/null +++ b/backend/resources/aaguid-icons/382fbdca2eb19cec.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/392d7b1382ef234c.svg b/backend/resources/aaguid-icons/392d7b1382ef234c.svg new file mode 100644 index 00000000..f48c5b8f --- /dev/null +++ b/backend/resources/aaguid-icons/392d7b1382ef234c.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/backend/resources/aaguid-icons/3931ecb62e3b6f2a.svg b/backend/resources/aaguid-icons/3931ecb62e3b6f2a.svg new file mode 100644 index 00000000..11170240 --- /dev/null +++ b/backend/resources/aaguid-icons/3931ecb62e3b6f2a.svg @@ -0,0 +1,76 @@ + +image/svg+xml \ No newline at end of file diff --git a/backend/resources/aaguid-icons/3c30e5f535168e89.svg b/backend/resources/aaguid-icons/3c30e5f535168e89.svg new file mode 100644 index 00000000..ff399889 --- /dev/null +++ b/backend/resources/aaguid-icons/3c30e5f535168e89.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/3ddddea0f68ee3b1.svg b/backend/resources/aaguid-icons/3ddddea0f68ee3b1.svg new file mode 100644 index 00000000..35357404 --- /dev/null +++ b/backend/resources/aaguid-icons/3ddddea0f68ee3b1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/backend/resources/aaguid-icons/46ac2bd17caa6d0b.svg b/backend/resources/aaguid-icons/46ac2bd17caa6d0b.svg new file mode 100644 index 00000000..aad6c5a1 --- /dev/null +++ b/backend/resources/aaguid-icons/46ac2bd17caa6d0b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/5301484de70d13e2.svg b/backend/resources/aaguid-icons/5301484de70d13e2.svg new file mode 100644 index 00000000..7e90bbb8 --- /dev/null +++ b/backend/resources/aaguid-icons/5301484de70d13e2.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/53eaed3308753caf.svg b/backend/resources/aaguid-icons/53eaed3308753caf.svg new file mode 100644 index 00000000..2a61bf86 --- /dev/null +++ b/backend/resources/aaguid-icons/53eaed3308753caf.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/54c30775685066bc.svg b/backend/resources/aaguid-icons/54c30775685066bc.svg new file mode 100644 index 00000000..450cef16 --- /dev/null +++ b/backend/resources/aaguid-icons/54c30775685066bc.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/55ed42788d41383d.svg b/backend/resources/aaguid-icons/55ed42788d41383d.svg new file mode 100644 index 00000000..8b303ea6 --- /dev/null +++ b/backend/resources/aaguid-icons/55ed42788d41383d.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/56f8d0a7f2afba25.svg b/backend/resources/aaguid-icons/56f8d0a7f2afba25.svg new file mode 100644 index 00000000..983f6d43 --- /dev/null +++ b/backend/resources/aaguid-icons/56f8d0a7f2afba25.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/5bca10e7f5aebe1d.svg b/backend/resources/aaguid-icons/5bca10e7f5aebe1d.svg new file mode 100644 index 00000000..fcb97d49 --- /dev/null +++ b/backend/resources/aaguid-icons/5bca10e7f5aebe1d.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/5cacab8124984715.svg b/backend/resources/aaguid-icons/5cacab8124984715.svg new file mode 100644 index 00000000..baab67db --- /dev/null +++ b/backend/resources/aaguid-icons/5cacab8124984715.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/5f7a884ad381ceaa.svg b/backend/resources/aaguid-icons/5f7a884ad381ceaa.svg new file mode 100644 index 00000000..603213e4 --- /dev/null +++ b/backend/resources/aaguid-icons/5f7a884ad381ceaa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/62ef07f809c7f588.svg b/backend/resources/aaguid-icons/62ef07f809c7f588.svg new file mode 100644 index 00000000..b13ae8a5 --- /dev/null +++ b/backend/resources/aaguid-icons/62ef07f809c7f588.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/72a52980cf2b1ed9.svg b/backend/resources/aaguid-icons/72a52980cf2b1ed9.svg new file mode 100644 index 00000000..ccf3e05d --- /dev/null +++ b/backend/resources/aaguid-icons/72a52980cf2b1ed9.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/75a96840f046f6f0.svg b/backend/resources/aaguid-icons/75a96840f046f6f0.svg new file mode 100644 index 00000000..3e7e9eea --- /dev/null +++ b/backend/resources/aaguid-icons/75a96840f046f6f0.svg @@ -0,0 +1 @@ +Edge_Logo_265x265 \ No newline at end of file diff --git a/backend/resources/aaguid-icons/7b0a06b33cb3cd3f.svg b/backend/resources/aaguid-icons/7b0a06b33cb3cd3f.svg new file mode 100644 index 00000000..4b2f5f45 --- /dev/null +++ b/backend/resources/aaguid-icons/7b0a06b33cb3cd3f.svg @@ -0,0 +1,63 @@ + + + Sticky Password Manager + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/7b4f712b63784561.svg b/backend/resources/aaguid-icons/7b4f712b63784561.svg new file mode 100644 index 00000000..6fe8a4df --- /dev/null +++ b/backend/resources/aaguid-icons/7b4f712b63784561.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/backend/resources/aaguid-icons/7d860a7c62be8a03.svg b/backend/resources/aaguid-icons/7d860a7c62be8a03.svg new file mode 100644 index 00000000..aac8009e --- /dev/null +++ b/backend/resources/aaguid-icons/7d860a7c62be8a03.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/7db3534fd5258565.svg b/backend/resources/aaguid-icons/7db3534fd5258565.svg new file mode 100644 index 00000000..b9716d72 --- /dev/null +++ b/backend/resources/aaguid-icons/7db3534fd5258565.svg @@ -0,0 +1 @@ +YubiKeyYubiKey \ No newline at end of file diff --git a/backend/resources/aaguid-icons/7f0646d4fff1e946.svg b/backend/resources/aaguid-icons/7f0646d4fff1e946.svg new file mode 100644 index 00000000..e0f82e19 --- /dev/null +++ b/backend/resources/aaguid-icons/7f0646d4fff1e946.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/7fd2cfb58273936e.svg b/backend/resources/aaguid-icons/7fd2cfb58273936e.svg new file mode 100644 index 00000000..2d8173cb --- /dev/null +++ b/backend/resources/aaguid-icons/7fd2cfb58273936e.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/80ced24b0dc2e7bf.svg b/backend/resources/aaguid-icons/80ced24b0dc2e7bf.svg new file mode 100644 index 00000000..0ea7851c --- /dev/null +++ b/backend/resources/aaguid-icons/80ced24b0dc2e7bf.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/851ebd6098a28f3a.svg b/backend/resources/aaguid-icons/851ebd6098a28f3a.svg new file mode 100644 index 00000000..2460a71d --- /dev/null +++ b/backend/resources/aaguid-icons/851ebd6098a28f3a.svg @@ -0,0 +1,4 @@ + + + + diff --git a/backend/resources/aaguid-icons/8bae707e5f61c50a.svg b/backend/resources/aaguid-icons/8bae707e5f61c50a.svg new file mode 100644 index 00000000..d3094ab6 --- /dev/null +++ b/backend/resources/aaguid-icons/8bae707e5f61c50a.svg @@ -0,0 +1 @@ +Password DepotPassword Depot circular key symbol in primary blue and controlled copper. \ No newline at end of file diff --git a/backend/resources/aaguid-icons/8f3d2a109e86bfc7.svg b/backend/resources/aaguid-icons/8f3d2a109e86bfc7.svg new file mode 100644 index 00000000..308242db --- /dev/null +++ b/backend/resources/aaguid-icons/8f3d2a109e86bfc7.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/8f995c717fd11cf3.svg b/backend/resources/aaguid-icons/8f995c717fd11cf3.svg new file mode 100644 index 00000000..764d273f --- /dev/null +++ b/backend/resources/aaguid-icons/8f995c717fd11cf3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/905e0b26ed90f80c.svg b/backend/resources/aaguid-icons/905e0b26ed90f80c.svg new file mode 100644 index 00000000..f23ec9e3 --- /dev/null +++ b/backend/resources/aaguid-icons/905e0b26ed90f80c.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/backend/resources/aaguid-icons/986d1b758c1c0666.svg b/backend/resources/aaguid-icons/986d1b758c1c0666.svg new file mode 100644 index 00000000..094897da --- /dev/null +++ b/backend/resources/aaguid-icons/986d1b758c1c0666.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/9b8cfdb7d699e942.svg b/backend/resources/aaguid-icons/9b8cfdb7d699e942.svg new file mode 100644 index 00000000..0c95ba00 --- /dev/null +++ b/backend/resources/aaguid-icons/9b8cfdb7d699e942.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/9d2487ab5b1de66c.svg b/backend/resources/aaguid-icons/9d2487ab5b1de66c.svg new file mode 100644 index 00000000..bd171507 --- /dev/null +++ b/backend/resources/aaguid-icons/9d2487ab5b1de66c.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/9f46d84e118605ca.svg b/backend/resources/aaguid-icons/9f46d84e118605ca.svg new file mode 100644 index 00000000..a4815b1d --- /dev/null +++ b/backend/resources/aaguid-icons/9f46d84e118605ca.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/a22945d6b8b2c855.svg b/backend/resources/aaguid-icons/a22945d6b8b2c855.svg new file mode 100644 index 00000000..0c4d1484 --- /dev/null +++ b/backend/resources/aaguid-icons/a22945d6b8b2c855.svg @@ -0,0 +1,91 @@ + +image/svg+xml diff --git a/backend/resources/aaguid-icons/a2983af5687c5c09.svg b/backend/resources/aaguid-icons/a2983af5687c5c09.svg new file mode 100644 index 00000000..08d95f27 --- /dev/null +++ b/backend/resources/aaguid-icons/a2983af5687c5c09.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/a547d13b2f7bee29.svg b/backend/resources/aaguid-icons/a547d13b2f7bee29.svg new file mode 100644 index 00000000..8cf8e7f3 --- /dev/null +++ b/backend/resources/aaguid-icons/a547d13b2f7bee29.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/a5a686d92796b3ff.svg b/backend/resources/aaguid-icons/a5a686d92796b3ff.svg new file mode 100644 index 00000000..06b528dc --- /dev/null +++ b/backend/resources/aaguid-icons/a5a686d92796b3ff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/a72a9761e0b6dd4b.svg b/backend/resources/aaguid-icons/a72a9761e0b6dd4b.svg new file mode 100644 index 00000000..b8dde9dc --- /dev/null +++ b/backend/resources/aaguid-icons/a72a9761e0b6dd4b.svg @@ -0,0 +1 @@ +Password DepotPassword Depot circular key symbol in primary blue and controlled copper on a white disc, for dark backgrounds. \ No newline at end of file diff --git a/backend/resources/aaguid-icons/a8a6898e204a3630.svg b/backend/resources/aaguid-icons/a8a6898e204a3630.svg new file mode 100644 index 00000000..c9e564e8 --- /dev/null +++ b/backend/resources/aaguid-icons/a8a6898e204a3630.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/a9773b88cb8d368a.svg b/backend/resources/aaguid-icons/a9773b88cb8d368a.svg new file mode 100644 index 00000000..49f658ff --- /dev/null +++ b/backend/resources/aaguid-icons/a9773b88cb8d368a.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/backend/resources/aaguid-icons/b8c6b04b104706c9.svg b/backend/resources/aaguid-icons/b8c6b04b104706c9.svg new file mode 100644 index 00000000..5f885502 --- /dev/null +++ b/backend/resources/aaguid-icons/b8c6b04b104706c9.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/b8db2a5d142953ed.svg b/backend/resources/aaguid-icons/b8db2a5d142953ed.svg new file mode 100644 index 00000000..a549a17d --- /dev/null +++ b/backend/resources/aaguid-icons/b8db2a5d142953ed.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/b9815d4fd9eb10a7.svg b/backend/resources/aaguid-icons/b9815d4fd9eb10a7.svg new file mode 100644 index 00000000..048052ae --- /dev/null +++ b/backend/resources/aaguid-icons/b9815d4fd9eb10a7.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/c1cfd304e92622af.svg b/backend/resources/aaguid-icons/c1cfd304e92622af.svg new file mode 100644 index 00000000..6a1da82d --- /dev/null +++ b/backend/resources/aaguid-icons/c1cfd304e92622af.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/c7b0f8dd95f195cf.svg b/backend/resources/aaguid-icons/c7b0f8dd95f195cf.svg new file mode 100644 index 00000000..5876600f --- /dev/null +++ b/backend/resources/aaguid-icons/c7b0f8dd95f195cf.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/backend/resources/aaguid-icons/c8448a372019a31d.svg b/backend/resources/aaguid-icons/c8448a372019a31d.svg new file mode 100644 index 00000000..dcd5b1ce --- /dev/null +++ b/backend/resources/aaguid-icons/c8448a372019a31d.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/c98f30b9093e282e.svg b/backend/resources/aaguid-icons/c98f30b9093e282e.svg new file mode 100644 index 00000000..a69a66c8 --- /dev/null +++ b/backend/resources/aaguid-icons/c98f30b9093e282e.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/cbc4ebc69a8d3188.svg b/backend/resources/aaguid-icons/cbc4ebc69a8d3188.svg new file mode 100644 index 00000000..e766618b --- /dev/null +++ b/backend/resources/aaguid-icons/cbc4ebc69a8d3188.svg @@ -0,0 +1,3 @@ + + + diff --git a/backend/resources/aaguid-icons/cc62b8c5575a65ae.svg b/backend/resources/aaguid-icons/cc62b8c5575a65ae.svg new file mode 100644 index 00000000..761c97ab --- /dev/null +++ b/backend/resources/aaguid-icons/cc62b8c5575a65ae.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/d09754c3034c4d86.svg b/backend/resources/aaguid-icons/d09754c3034c4d86.svg new file mode 100644 index 00000000..a6f67034 --- /dev/null +++ b/backend/resources/aaguid-icons/d09754c3034c4d86.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/d6098dee8bf5800c.svg b/backend/resources/aaguid-icons/d6098dee8bf5800c.svg new file mode 100644 index 00000000..39903394 --- /dev/null +++ b/backend/resources/aaguid-icons/d6098dee8bf5800c.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/db8f0d82e2ffc1a4.svg b/backend/resources/aaguid-icons/db8f0d82e2ffc1a4.svg new file mode 100644 index 00000000..f2e2b2be --- /dev/null +++ b/backend/resources/aaguid-icons/db8f0d82e2ffc1a4.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/e5f7c847e7bb1823.svg b/backend/resources/aaguid-icons/e5f7c847e7bb1823.svg new file mode 100644 index 00000000..30f4f117 --- /dev/null +++ b/backend/resources/aaguid-icons/e5f7c847e7bb1823.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/e63a433d41e3bbd1.svg b/backend/resources/aaguid-icons/e63a433d41e3bbd1.svg new file mode 100644 index 00000000..960a7af5 --- /dev/null +++ b/backend/resources/aaguid-icons/e63a433d41e3bbd1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/e8ae0a4206de8b1f.svg b/backend/resources/aaguid-icons/e8ae0a4206de8b1f.svg new file mode 100644 index 00000000..95ffd3e0 --- /dev/null +++ b/backend/resources/aaguid-icons/e8ae0a4206de8b1f.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/resources/aaguid-icons/faac7e28bcf9ba73.svg b/backend/resources/aaguid-icons/faac7e28bcf9ba73.svg new file mode 100644 index 00000000..3cf034bb --- /dev/null +++ b/backend/resources/aaguid-icons/faac7e28bcf9ba73.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend/resources/aaguid-icons/fe2583b9176a3347.svg b/backend/resources/aaguid-icons/fe2583b9176a3347.svg new file mode 100644 index 00000000..367d2b49 --- /dev/null +++ b/backend/resources/aaguid-icons/fe2583b9176a3347.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/resources/aaguids.json b/backend/resources/aaguids.json index a3e31213..7af9589f 100644 --- a/backend/resources/aaguids.json +++ b/backend/resources/aaguids.json @@ -1 +1,1293 @@ -{"fcb1bcb4-f370-078c-6993-bc24d0ae3fbe":"Ledger Nano X FIDO2 Authenticator","6e8d1eae-8d40-4c25-bcf8-4633959afc71":"Veridium iOS SDK","e8b7f4a2-c3d5-e6f7-890a-b1c2d3e4f567":"Sherlocked","51787637-8ab8-460c-9302-de0b853d4ffb":"SpearID FIDO2 Standard","9eb7eabc-9db5-49a1-b6c3-555a802093f4":"YubiKey 5 Series with NFC KVZR57","4d41190c-7beb-4a84-8018-adf265a6352d":"Thales IDPrime FIDO Bio","2772ce93-eb4b-4090-8b73-330f48477d73":"Security Key NFC by Yubico - Enterprise Edition Preview","6dae43be-af9c-417b-8b9f-1b611168ec60":"Dapple Authenticator from Dapple Security Inc.","5626bed4-e756-430b-a7ff-ca78c8b12738":"VALMIDO PRO FIDO","260e3021-482d-442d-838c-7edfbe153b7e":"Feitian ePass FIDO2-NFC Plus Authenticator","95e4d58c-056e-4a65-866d-f5a69659e880":"TruU Windows Authenticator","90636e1f-ef82-43bf-bdcf-5255f139d12f":"YubiKey Bio Series - Multi-protocol Edition","9c835346-796b-4c27-8898-d6032f515cc5":"Cryptnox FIDO2","c3f47802-de73-4dfc-ba22-671fe3304f90":"eToken Fusion NFC PIV Enterprise","0d9b2e56-566b-c393-2940-f821b7f15d6d":"Excelsecu eSecu FIDO2 Pro Security Key","2bff89f2-323a-48fc-b7c8-9ff7fe87c07e":"Feitian BioPass FIDO2 Pro (Enterprise Profile)","c5ef55ff-ad9a-4b9f-b580-adebafe026d0":"YubiKey 5 Series with Lightning","2194b428-9397-4046-8f39-007a1605a482":"IDPrime 931 Fido","39a5647e-1853-446c-a1f6-a79bae9f5bc7":"IDmelon","664d9f67-84a2-412a-9ff7-b4f7d8ee6d05":"OpenSK authenticator","3789da91-f943-46bc-95c3-50ea2012f03a":"NEOWAVE Winkeo FIDO2","fa2b99dc-9e39-4257-8f92-4a30d23c4118":"YubiKey 5 Series with NFC","341e4da9-3c2e-8103-5a9f-aad887135200":"Ledger Nano S FIDO2 Authenticator","69700f79-d1fb-472e-bd9b-a3a3b9a9eda0":"Pone Biometrics OFFPAD Authenticator","8da0e4dc-164b-454e-972e-88f362b23d59":"CardOS FIDO2 Token","89b19028-256b-4025-8872-255358d950e4":"Sentry Enterprises CTAP2 Authenticator","4e768f2c-5fab-48b3-b300-220eb487752b":"Hideez Key 4 FIDO2 SDK","47ab2fb4-66ac-4184-9ae1-86be814012d5":"Security Key NFC by Yubico - Enterprise Edition","931327dd-c89b-406c-a81e-ed7058ef36c6":"Swissbit iShield Key FIDO2","f8d5c4e9-e539-4c06-8662-ec2a4155a555":"StarSign Key Fob","b7d3f68e-88a6-471e-9ecf-2df26d041ede":"Security Key NFC by Yubico","8d1b1fcb-3c76-49a9-9129-5515b346aa02":"IDEMIA ID-ONE Card","30b5035e-d297-4ff7-020b-addc96ba6a98":"OneSpan DIGIPASS FX7","454e5346-4944-4ffd-6c93-8e9267193e9a":"Ensurity ThinC","e1a96183-5016-4f24-b55b-e3ae23614cc6":"ATKey.Pro CTAP2.0","9ff4cc65-6154-4fff-ba09-9e2af7882ad2":"Security Key NFC by Yubico - Enterprise Edition (Enterprise Profile)","4599062e-6926-4fe7-9566-9e8fb1aedaa0":"YubiKey 5 Series (Enterprise Profile)","9d3df6ba-282f-11ed-a261-0242ac120002":"Arculus FIDO2/U2F Key Card","fbefdf68-fe86-0106-213e-4d5fa24cbe2e":"Excelsecu eSecu FIDO2 NFC Security Key","62e54e98-c209-4df3-b692-de71bb6a8528":"YubiKey 5 FIPS Series with NFC Preview","ab32f0c6-2239-afbb-c470-d2ef4e254db7":"TOKEN2 FIDO2 Security Key","ce6bf97f-9f69-4ba7-9032-97adc6ca5cf1":"YubiKey 5 FIPS Series with NFC (RC Preview)","ad08c78a-4e41-49b9-86a2-ac15b06899e2":"YubiKey Bio Series - FIDO Edition (Enterprise Profile)","930b0c03-ef46-4ac4-935c-538dccd1fcdb":"Chipwon Clife Key","7787a482-13e8-4784-8a06-c7ed49a7aaf4":"Swissbit iShield Key 2","72c6b72d-8512-4c66-8359-9d3d10d9222f":"Security Key NFC by Yubico - Enterprise Edition (Enterprise Profile)","99ed6c29-4573-4847-816d-78ad8f1c75ef":"VeroCard FIDO2 Authenticator","973446ca-e21c-9a9b-99f5-9b985a67af0f":"ACS FIDO Authenticator Card","238ab2f5-b57f-4917-b3c6-3d3c6c0c350f":"FEITIAN FT-JCOS BioCard","74820b05-a6c9-40f9-8fb0-9f86aca93998":"SafeNet eToken Fusion","1105e4ed-af1d-02ff-ffff-ffffffffffff":"Egomet FIDO2 Authenticator for Android","08987058-cadc-4b81-b6e1-30de50dcbe96":"Windows Hello","a4e9fc6d-4cbe-4758-b8ba-37598bb5bbaa":"Security Key NFC by Yubico","8caf7e7b-6c8b-46a9-b36b-5d04740d7463":"cryptovision ePasslet Suite FIDO Authenticator","0acf3011-bc60-f375-fb53-6f05f43154e0":"Nymi FIDO2 Authenticator","d91c5288-0ef0-49b7-b8ae-21ca0aa6b3f3":"KEY-ID FIDO2 Authenticator","8eec9bf9-486c-46da-9a67-1fbb4f66b9ed":"HID Crescendo 4000 FIPS","4c50ff10-1057-4fc6-b8ed-43a529530c3c":"ImproveID Authenticator","c611b55c-77b2-4527-8082-590e931b2f08":"GoTrust Idem Key ","ee041bce-25e5-4cdb-8f86-897fd6418464":"Feitian ePass FIDO2-NFC Authenticator","2588ae83-5a3b-4536-b8de-5e540200d191":"Dapple Authenticator from Dapple Security Inc.","4b89f401-464e-4745-a520-486ddfc5d80e":"IIST FIDO2 Authenticator","2cd2f727-f6ca-44da-8f48-5c2e5da000a2":"Nitrokey 3 AM","10c70715-2a9a-4de1-b0aa-3cff6d496d39":"eToken Fusion NFC FIPS","efb96b10-a9ee-4b6c-a4a9-d32125ccd4a4":"Safenet eToken FIDO","24083bcb-3034-4867-99de-a3b52e1d426a":"Enterprise Security Key Series with NFC (Consumer Profile)","4b3f8944-d4f2-4d21-bb19-764a986ec160":"KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2 Authenticator","4c0cf95d-2f40-43b5-ba42-4c83a11c04ba":"Feitian BioPass FIDO2 Pro Authenticator","5343502d-5343-5343-6172-644649444f32":"ESS Smart Card Inc. Authenticator","69e7c36f-f2f6-9e0d-07a6-bcc243262e6b":"OneKey FIDO2 Authenticator","524de2de-982f-49b4-a769-2b5e3b73ad79":"YubiKey 5 Series (Enterprise Profile)","09591fc6-9811-48f7-8f57-b9f23df6413f":"Pone Biometrics OFFPAD Authenticator","912435d9-4a88-42f3-972d-1244b0d51420":"SI0X FIDO CL WRIST v1.0","7e3f3d30-3557-4442-bdae-139312178b39":"RSA DS100","73bb0cd4-e502-49b8-9c6f-b59445bf720b":"YubiKey 5 FIPS Series","39589099-9a75-49fc-afaa-801ca211c62a":"Feitian ePass FIDO-NFC (Enterprise Profile) (CTAP2.1, CTAP2.0, U2F)","dc5e949d-f939-43b3-9877-a85c7186b753":"YubiKey Bio Multi-protocol Edition (Enterprise Profile)","149a2021-8ef6-4133-96b8-81f8d5b7f1f5":"Security Key by Yubico with NFC","5df66f62-5b47-43d3-aa1d-a6e31c8dbeb5":"Securitag Assembly Group FIDO Authenticator NFC","9a272558-5cfa-4424-be37-65509677b77d":"SECORA ID Key S USB by Infineon Consumer Edition","09619fbf-d75e-4a62-be1d-fe4d240864ae":"VeriMark(TM) Guard 2.1 Fingerprint Security Key","55fd881f-40ba-4eaf-8435-42c5fed08b76":"SECORA ID V2 by Infineon Consumer Edition","50cbf15a-238c-4457-8f16-812c43bf3c49":"Ensurity AUTH TouchPro","ee7fa1e0-9539-432f-bd43-9c2fc6d4f311":"VeriMark NFC+ USB-C Security Key","b90e7dc1-316e-4fee-a25a-56a666a670fe":"YubiKey 5 Series with Lightning (Enterprise Profile)","6d4aa745-dad5-40c4-b9b4-6a252fcee70f":"GoTrust Cyber Key","175cd298-83d2-4a26-b637-313c07a6434e":"Chunghwa Telecom FIDO2 Smart Card Authenticator","34744913-4f57-4e6e-a527-e9ec3c4b94e6":"YubiKey Bio Series - Multi-protocol Edition","5ea308b2-7ac7-48b9-ac09-7e2da9015f8c":"Veridium Android SDK","3b1adb99-0dfe-46fd-90b8-7f7614a4de2a":"GoTrust Idem Key","46544d5d-8f5d-4db4-89ac-ea8977073fff":"Foongtone FIDO Authenticator","0a357157-9b18-4c8a-920e-d156e972b2f8":"YubiKey 5 Series (Consumer Profile)","998f358b-2dd2-4cbe-a43a-e8107438dfb3":"OnlyKey Secp256R1 FIDO2 CTAP2 Authenticator","30b5035e-d297-4ff2-010b-addc96ba6a98":"OneSpan DIGIPASS FX2-A","817cdab8-0d51-4de1-a821-e25b88519cf3":"Swissbit iShield Key 2 FIPS","61250591-b2bc-4456-b719-0b17be90bb30":"eWBM eFPA FIDO2 Authenticator","8c39ee86-7f9a-4a95-9ba3-f6b097e5c2ee":"YubiKey Bio Series - FIDO Edition (Enterprise Profile)","f8a011f3-8c0a-4d15-8006-17111f9edc7d":"Security Key by Yubico","8976631b-d4a0-427f-5773-0ec71c9e0279":"Solo Tap Secp256R1 FIDO2 CTAP2 Authenticator","7dab85a5-d16d-4eaf-a7ef-4c1385b151c5":"YubiKey 5 Series with NFC (Consumer Profile) KVZR57-2","516d3969-5a57-5651-5958-4e7a49434167":"SmartDisplayer BobeePass FIDO2 Authenticator","8681a073-5f50-4d52-bce4-e21658d207b3":"RSA Authenticator 4 for iOS","30b5035e-d297-4ff7-030b-addc96ba6a98":"OneSpan DIGIPASS FX7-C","e41b42a3-60ac-4afb-8757-a98f2d7f6c9f":"Deepnet SafeKey/Classic (FP)","c89e6a38-6c00-5426-5aa5-c9cbf48f0382":"ACS FIDO Authenticator NFC","11544c3c-3693-40ba-9dbb-3b8d2b977988":"Thales PAY GFCX20.1 authenticator","eb7ef748-cbe0-4b40-b8f6-07bd2d592d35":"YubiKey 5 CCN Series with NFC (Consumer Profile)","a02167b9-ae71-4ac7-9a07-06432ebb6f1c":"YubiKey 5 Series with Lightning","82b0a720-127a-4788-b56d-d1d4b2d82eac":"ID-One Key","6169eb16-f87a-42d8-978d-e1ac0c3f319f":"GoTrust Idem Card","2c0df832-92de-4be1-8412-88a8f074df4a":"Feitian FIDO Smart Card","59f85fe7-faa5-4c92-9f52-697b9d4d5473":"RSA Authenticator 4 for Android","22682ee5-4f0e-4c19-be3e-797d5770ebfe":"Precision InnaIT Key FIDO 2 Level 2 certified","0fbb74b5-f1ac-4f14-a0f1-ec39b5edfdae":"Thales PAY GFCX19 authenticator","79f3c8ba-9e35-484b-8f47-53a5a0f5c630":"YubiKey 5 FIPS Series with NFC (Enterprise Profile)","6e34341a-88c7-483d-b777-a425c355be93":"WebComm OETHenticator","7a53c643-9dec-4219-b3a4-f9d24aca4e12":"G+D StarKey FIDO2-NFC","19bca99b-7c09-44fe-a969-8cba45764542":"HID Crescendo Key V3 FIPS","def8ab1a-9f91-44f1-a103-088d8dc7d681":"IDEMIA SOLVO Fly 80 R3 FIDO Card e","9955a1cd-564c-d388-ad68-9878a27be9f1":"StarSign Chase FIDO Card","9dd8d593-2213-438a-97f8-d6b813d51c27":"YubiKey Bio Fido Edition (Consumer Profile)","970c8d9c-19d2-46af-aa32-3f448db49e35":"WinMagic FIDO Eazy - TPM","c5703116-972b-4851-a3e7-ae1259843399":"NEOWAVE Badgeo FIDO2","c80dbd9a-533f-4a17-b941-1a2f1c7cedff":"HID Crescendo C3000","0b8b05a4-ebd4-4b0b-8f5f-33d7b6e606ab":"HID Crescendo 4000","5b0e46ba-db02-44ac-b979-ca9b84f5e335":"YubiKey 5 FIPS Series with Lightning Preview","12755c32-8ad1-46eb-881c-e0b38d848b09":"Feitian ePass FIDO Authenticator (CTAP2.1, CTAP2.0, U2F)","2a55aee6-27cb-42c0-bc6e-04efe999e88a":"HID Crescendo 4000","820d89ed-d65a-409e-85cb-f73f0578f82a":"IDmelon Authenticator","019614a3-2703-7e35-a453-285fd06c5d24":"ATLKey Authenticator","3124e301-f14e-4e38-876d-fbeeb090e7bf":"YubiKey 5 Series with Lightning Preview","b6ede29c-3772-412c-8a78-539c1f4c62d2":"Feitian BioPass FIDO2 Plus Authenticator","ed042a3a-4b22-4455-bb69-a267b652ae7e":"Security Key NFC by Yubico - Enterprise Edition","b2c1a50b-dad8-4dc7-ba4d-0ce9597904bc":"YubiKey 5 Series with NFC - Enhanced PIN (Enterprise Profile)","85203421-48f9-4355-9bc8-8a53846e5083":"YubiKey 5 FIPS Series with Lightning","fcc0118f-cd45-435b-8da1-9782b2da0715":"YubiKey 5 FIPS Series with NFC","d821a7d4-e97c-4cb6-bd82-4237731fd4be":"Hyper FIDO Bio Security Key","9876631b-d4a0-427f-5773-0ec71c9e0279":"Somu Secp256R1 FIDO2 CTAP2 Authenticator","522a3f91-5f5d-480d-be37-6cecfad5a27b":"Precision InnaIT Key FIDO 2 Level 2 certified","f56f58b3-d711-4afc-ba7d-6ac05f88cb19":"WinMagic FIDO Eazy - Phone","6ec5cff2-a0f9-4169-945b-f33b563f7b99":"YubiKey Bio Series - Multi-protocol Edition (Enterprise Profile)","882adaf5-3aa9-4708-8e7d-3957103775b4":"T-Shield TrustSec FIDO2 Bio and client PIN version","49a15c1c-3f63-3f51-23a7-b9e00096edd1":"IDEX CTAP2.1 Biometrics","f4c63eff-d26c-4248-801c-3736c7eaa93a":"FIDO KeyPass S3","d384db22-4d50-ebde-2eac-5765cf1e2a44":"Excelsecu eSecu FIDO2 Fingerprint Security Key","0db01cd6-5618-455b-bb46-1ec203d3213e":"GoldKey Security Token","b93fd961-f2e6-462f-b122-82002247de78":"Android Authenticator","aa79f476-ea00-417e-9628-1e8365123922":"HID Crescendo 4000 FIDO","1e906e14-77af-46bc-ae9f-fe6ef18257e4":"VeridiumID Passkey iOS SDK","2fc0579f-8113-47ea-b116-bb5a8db9202a":"YubiKey 5 Series with NFC","31c3f7ff-bf15-4327-83ec-9336abcbcd34":"WinMagic FIDO Eazy - Software","cb4f796c-a20a-af9e-d639-213c1ec247f3":"ACS PocketKey+ Bio","686de81e-fff2-41c1-bb83-2723aaf3e913":"IIST SASE USB KEY 1","9ddd1817-af5a-4672-a2b9-3e3dd95000a9":"Windows Hello","18852056-063b-4042-9814-7d0d383081f9":"SECORA ID Key S USB by Infineon Enterprise Edition","d8522d9f-575b-4866-88a9-ba99fa02f35b":"YubiKey Bio Series - FIDO Edition","050dd0bc-ff20-4265-8d5d-305c4b215192":"eToken Fusion FIPS","50a45b0c-80e7-f944-bf29-f552bfa2e048":"ACS FIDO Authenticator","f7c558a0-f465-11e8-b568-0800200c9a66":"KONAI Secp256R1 FIDO2 Conformance Testing CTAP2 Authenticator","3f59672f-20aa-4afe-b6f4-7e5e916b6d98":"Arculus FIDO 2.1 Key Card [P71]","42b4fb4a-2866-43b2-9bf7-6c6669c2e5d3":"Google Titan Security Key v2","361a3082-0278-4583-a16f-72a527f973e4":"eWBM eFA500 FIDO2 Authenticator","2ffd6452-01da-471f-821b-ea4bf6c8676a":"IDPrime 941 Fido","9806a2c8-c0da-478e-b4ca-620005d34182":"YubiKey Bio Multi-protocol Edition (Consumer Profile) 1VDJSN-2","03012cb7-4fb2-42e7-9e8d-a81f10e2a5e9":"YubiKey 5 Series with Lightning (Consumer Profile)","30b5035e-d297-4ff7-b00b-addc96ba6a98":"OneSpan DIGIPASS FX7","0f083f18-4105-43a8-ad69-24e812e38141":"Security Key Series with NFC (Consumer Profile)","5eaff75a-dd43-451f-af9f-87c9eeae293e":"Swissbit iShield Key 2 FIPS Enterprise","b415094c-49d3-4c8b-b3fe-7d0ad28a6bc4":"ZTPass SmartAuth","692db549-7ae5-44d5-a1e5-dd20a493b723":"HID Crescendo Key","0ebd9f2c-f685-441c-8c3e-a02a234a840a":"YubiKey 5 Series with NFC Enhanced PIN (Consumer Profile)","23315ad0-6aca-4ba1-952e-f044f1e36976":"Clife Key 2 NFC","1d1b4e33-76a1-47fb-97a0-14b10d0933f1":"Cryptnox FIDO2.1","bbf4b6a7-679d-f6fc-c4f2-8ac0ddf9015a":"Excelsecu eSecu FIDO2 PRO Security Key","3e22415d-7fdf-4ea4-8a0c-dd60c4249b9d":"Feitian iePass FIDO Authenticator","ab7d1767-3fa0-4388-b6c4-feef7a844809":"Enterprise Security Key Series with NFC (Enterprise Profile)","f4ce5fc0-57d3-46f5-a736-efb7d5bc63b5":"YubiKey 5 Series with NFC (Consumer Profile)","23786452-f02d-4344-87ed-aaf703726881":"SafeNet eToken Fusion CC","5e264d9d-28ef-4d34-95b4-5941e7a4faa8":"Ideem ZSM FIDO2 Authenticator","d2fbd093-ee62-488d-9dad-1e36389f8826":"YubiKey 5 FIPS Series (RC Preview)","234cd403-35a2-4cc2-8015-77ea280c77f5":"Feitian ePass FIDO2-NFC Series (CTAP2.1, CTAP2.0, U2F)","6999180d-630c-442d-b8f7-424b90a43fae":"Hyper FIDO Pro (CTAP2.1, CTAP2.0, U2F)","662ef48a-95e2-4aaa-a6c1-5b9c40375824":"YubiKey 5 Series with NFC - Enhanced PIN","aeb6569c-f8fb-4950-ac60-24ca2bbe2e52":"HID Crescendo C2300","87dbc5a1-4c94-4dc8-8a47-97d800fd1f3c":"eWBM eFA320 FIDO2 Authenticator","58276709-bb4b-4bb3-baf1-60eea99282a7":"YubiKey Bio Series - Multi-protocol Edition 1VDJSN","7d2afadd-bf6b-44a2-a66b-e831fceb8eff":"Taglio CTAP2.1 EP","30b5035e-d297-4ff1-020b-addc96ba6a98":"OneSpan DIGIPASS FX1-C","04a8fcf2-19c1-457b-911e-69219f17583f":"Thales PAY GFCX13 authenticator","20ac7a17-c814-4833-93fe-539f0d5e3389":"YubiKey 5 Series (Enterprise Profile)","9012593f-43e4-4461-a97a-d92777b55d74":"VinCSS FIDO2 Fingerprint","d7781e5d-e353-46aa-afe2-3ca49f13332a":"YubiKey 5 Series with NFC","9f0d8150-baa5-4c00-9299-ad62c8bb4e87":"GoTrust Idem Card","12ded745-4bed-47d4-abaa-e713f51d6393":"Feitian AllinOne FIDO2 Authenticator","88bbd2f0-342a-42e7-9729-dd158be5407a":"Precision InnaIT Key FIDO 2 Level 2 certified","1d8cac46-47a1-3386-af50-e88ae46fe802":"Ledger Flex FIDO2 Authenticator","dd86a2da-86a0-4cbe-b462-4bd31f57bc6f":"YubiKey Bio Series - FIDO Edition","773c30d9-5919-4e96-a4f5-db65e95cf890":"GSTAG OAK FIDO2 Authenticator","34f5766d-1536-4a24-9033-0e294e510fb0":"YubiKey 5 Series with NFC Preview","83c47309-aabb-4108-8470-8be838b573cb":"YubiKey Bio Series - FIDO Edition (Enterprise Profile)","c1288a5c-d66b-495c-a68f-4e81f9ec5b53":"Deepnet SafeKey/Classic (FP) XF","4e2ddbc2-2687-4709-8551-cb66c9776bfe":"SECORA ID V2 FIDO2.1 L1","be727034-574a-f799-5c76-0929e0430973":"Crayonic KeyVault K1 (USB-NFC-BLE FIDO2 Authenticator)","092277e5-8437-46b5-b911-ea64b294acb7":"Taglio CTAP2.1 CS","ca87cb70-4c1b-4579-a8e8-4efdd7c007e0":"FIDO Alliance TruU Sample FIDO2 Authenticator","23195a52-62d9-40fa-8ee5-23b173f4fb52":"Hyper FIDO Pro NFC","ba0a9266-40d8-4048-9786-d710b5474752":"YubiKey Bio Multi-protocol Edition (Consumer Profile)","3e9db280-256a-4e17-b08e-19d79e9be166":"SECORA ID V2 by Infineon Pay Edition","a7fc3f84-86a3-4da4-a3d7-eb6485a066d8":"NEOWAVE Badgeo FIDO2 (CTAP 2.1)","8791f7dc-418b-4510-bbf5-3baf30715324":"Virtual FIDO2 authenticator for Linux-based systems","1f8e43df-71ff-e11d-bea3-c4ee7003b232":"Thetis Pro FIDO2 Key","3ec9c8d3-a5a7-415b-a7b5-f1d606368d3f":"YubiKey 5 CCN Series with NFC (Enterprise Profile)","9e66c661-e428-452a-a8fb-51f7ed088acf":"YubiKey 5 FIPS Series with Lightning (RC Preview)","58b44d0b-0a7c-f33a-fd48-f7153c871352":"Ledger Nano S Plus FIDO2 Authenticator","9a3f2abd-a73d-439c-9ee7-1b53a857eaa7":"YubiKey 5 Series with NFC Enhanced PIN (Enterprise Profile)","454e5346-4944-4ffd-6c93-8e9267193e9b":"Ensurity AUTH BioPro","41e39911-c669-4811-b860-c6ad0b411b96":"YubiKey 5 Series with NFC (Enterprise Profile)","146e77ef-11eb-4423-b847-ce77864e9411":"eToken Fusion NFC PIV","13ac47cf-1d78-4fd5-9060-aedaabacf826":"HID Crescendo Key V3 - Enterprise Edition","e77e3c64-05e3-428b-8824-0cbeb04b829d":"Security Key NFC by Yubico","33d6d7d0-279f-4ef3-96b3-2d3282f4bde6":"Thales eToken Fusion BIO Enterprise","8d4378b0-725d-4432-b3c2-01fcdaf46286":"VeridiumID Passkey Android SDK","7409272d-1ff9-4e10-9fc9-ac0019c124fd":"YubiKey Bio Series - FIDO Edition","bb66c294-de08-47e4-b7aa-d12c2cd3fb20":"Mettlesemi Vishwaas Hawk Authenticator using FIDO2","c4ddaf11-3032-4e77-b3b9-3a340369b9ad":"HID Crescendo Fusion","add92433-0d69-4026-8166-29b25bce64e9":"YubiKey Bio Fido Edition (Enterprise Profile)","7d1351a6-e097-4852-b8bf-c9ac5c9ce4a3":"YubiKey Bio Series - Multi-protocol Edition","07a9f89c-6407-4594-9d56-621d5f1e358b":"NXP Semiconductros FIDO2 Conformance Testing CTAP2 Authenticator","d61d3b87-3e7c-4aea-9c50-441c371903ad":"KeyVault Secp256R1 FIDO2 CTAP2 Authenticator","c62100de-759b-4bf8-b22b-63b3e3a80401":"Token Ring 3 FIDO2 Authenticator","5ca1ab1e-1337-fa57-f1d0-a117e71ca702":"Allthenticator iOS App: roaming BLE FIDO2 Allthenticator for Windows, Mac, Linux, and Allthenticate door readers","b92c3f9a-c014-4056-887f-140a2501163b":"Security Key by Yubico","54d9fee8-e621-4291-8b18-7157b99c5bec":"HID Crescendo Enabled","72a2b5b1-95a5-4df9-a881-4192aff4f72e":"GoTrust Idem Key mini","a25342c0-3cdc-4414-8e46-f4807fca511c":"YubiKey 5 Series with NFC","3a662962-c6d4-4023-bebb-98ae92e78e20":"YubiKey 5 FIPS Series with Lightning (Enterprise Profile)","20f0be98-9af9-986a-4b42-8eca4acb28e4":"Excelsecu eSecu FIDO2 Fingerprint Security Key","ca4cff1b-5a81-4404-8194-59aabcf1660b":"IDPrime 3930 FIDO","ab32f0c6-2239-afbb-c470-d2ef4e254db6":"TEST (DUMMY RECORD)","760eda36-00aa-4d29-855b-4012a182cdeb":"Security Key NFC by Yubico Preview","6028b017-b1d4-4c02-b4b3-afcdafc96bb2":"Windows Hello","b12eac35-586c-4809-a4b1-d81af6c305cf":"Deepnet SafeKey/Classic (NFC)","30b5035e-d297-4fc1-b00b-addc96ba6a97":"OneSpan FIDO Touch","560a780c-b6ae-4f03-b110-082f856425b4":"KQC QuKey Bio FIDO2 Authenticator","1ac71f64-468d-4fe0-bef1-0e5f2f551f18":"YubiKey 5 Series with NFC (Enterprise Profile)","6d44ba9b-f6ec-2e49-b930-0c8fe920cb73":"Security Key by Yubico with NFC","b68c4b8d-65cb-42ae-b4f6-8606dfba3c22":"IDEMIA SOLVO Fly 80 R3 FIDO Card for j","6832d205-75f2-44c7-a864-e868c796d06e":"Precision InnaIT Key FIDO 2 Level 2 certified","9eb85bb6-9625-4a72-815d-0487830ccab2":"Ensurity AUTH BioPro Desktop","30b5035e-d297-4ff7-010b-addc96ba6a98":"OneSpan DIGIPASS FX7-B","5ca1ab1e-fa57-1337-f1d0-a117371ca702":"Allthenticator Android App: roaming BLE FIDO2 Allthenticator for Windows, Mac, Linux, and Allthenticate door readers","eabb46cc-e241-80bf-ae9e-96fa6d2975cf":"TOKEN2 PIN Plus Security Key Series ","53414d53-554e-4700-0000-000000000000":"Samsung Pass","e416201b-afeb-41ca-a03d-2281c28322aa":"ATKey.Pro CTAP2.1","905b4cb4-ed6f-4da9-92fc-45e0d4e9b5c7":"YubiKey 5 FIPS Series (Enterprise Profile)","dee49ee1-11cb-47b6-bed0-8e995e67a0fb":"SECORA Connect SLS21 D1 FIDO 2.1 v1.0 by Infineon - Consumer Edition","cfcb13a2-244f-4b36-9077-82b79d6a7de7":"USB/NFC Passcode Authenticator","76692dc1-c56a-48d9-8e7d-31b5ced430ac":"VeriMark NFC+ USB-A Security Key","91ad6b93-264b-4987-8737-3a690cad6917":"Token Ring FIDO2 Authenticator","a02140b7-0cbd-42e1-a9b5-a39da2545114":"Feitian BioPass FIDO2 Plus (Enterprise Profile)","5753362b-4e6b-6345-7b2f-255438404c75":"WiSECURE Blentity FIDO2 Authenticator","9f77e279-a6e2-4d58-b700-31e5943c6a98":"Hyper FIDO Pro","b9f6b7b6-f929-4189-bca9-dd951240c132":"Deepnet SafeKey/Classic (USB)","cc45f64e-52a2-451b-831a-4edd8022a202":"ToothPic Passkey Provider","0bb43545-fd2c-4185-87dd-feb0b2916ace":"Security Key NFC by Yubico - Enterprise Edition","73402251-f2a8-4f03-873e-3cb6db604b03":"uTrust FIDO2 Security Key","c1f9a0bc-1dd2-404a-b27f-8e29047a43fd":"YubiKey 5 FIPS Series with NFC","70e7c36f-f2f6-9e0d-07a6-bcc243262e6b":"OneKey FIDO2 Bluetooth Authenticator","4fc84f16-2545-4e53-b8fc-7bf4d7282a10":"YubiKey 5 CCN Series with NFC (Enterprise Profile)","6ab56fad-881f-4a43-acb2-0be065924522":"YubiKey 5 Series with NFC (Enterprise Profile)","504d7149-4e4c-3841-4555-55445a677357":"WiSECURE AuthTron USB FIDO2 Authenticator","2c2aeed8-8174-4159-814b-486e92a261d0":"NEOWAVE WINKEO V2.0","f2145e86-211e-4931-b874-e22bba7d01cc":"ID-One Key","53334693-4b3f-4198-8857-53772de2ab65":"Precision InnaIT Key FIDO 2 Level 2 certified","a3975549-b191-fd67-b8fb-017e2917fdb3":"Excelsecu eSecu FIDO2 NFC Security Key","19083c3d-8383-4b18-bc03-8f1c9ab2fd1b":"YubiKey 5 Series","da1fa263-8b25-42b6-a820-c0036f21ba7f":"ATKey.Card NFC","6002f033-3c07-ce3e-d0f7-0ffe5ed42543":"Excelsecu eSecu FIDO2 Fingerprint Key","5fdb81b8-53f0-4967-a881-f5ec26fe4d18":"VinCSS FIDO2 Authenticator","78ba3993-d784-4f44-8d6e-cc0a8ad5230e":"Feitian ePass FIDO-NFC(CTAP2.1, CTAP2.0, U2F)","57f7de54-c807-4eab-b1c6-1c9be7984e92":"YubiKey 5 FIPS Series","bb405265-40cf-4115-93e5-a332c1968d8c":"ID-One Card","2d3bec26-15ee-4f5d-88b2-53622490270b":"HID Crescendo Key V2","489ff376-b48d-6640-bb69-782a860ca795":"Mettlesemi Vishwaas Eagle Authenticator using FIDO2","3b24bf49-1d45-4484-a917-13175df0867b":"YubiKey 5 Series with Lightning (Enterprise Profile)","30b5035e-d297-4ff1-010b-addc96ba6a98":"OneSpan DIGIPASS FX1a","cb69481e-8ff7-4039-93ec-0a2729a154a8":"YubiKey 5 Series","0076631b-d4a0-427f-5773-0ec71c9e0279":"HYPR FIDO2 Authenticator","d716019a-9f4e-4041-9750-17c78f8ae81a":"eToken Fusion BIO","57235694-51a5-4a4d-a81a-f42185df6502":"SHALO AUTH","24673149-6c86-42e7-98d9-433fb5b73296":"YubiKey 5 Series with Lightning","357f2718-434f-4124-8a58-7e28c5e4a2fc":"Deepnet SafeKey/Classic (NFC)","42df17de-06ba-4177-a2bb-6701be1380d6":"Feitian BioPass FIDO2 Plus Authenticator","d7a423ad-3e19-4492-9200-78137dccc136":"VivoKey Apex FIDO2","b3315166-f36c-b05f-fea8-66a3dfdad171":"Ledger Nano Gen5 FIDO2 Authenticator","ba76a271-6eb6-4171-874d-b6428dbe3437":"ATKey.ProS","97e6a830-c952-4740-95fc-7c78dc97ce47":"YubiKey Bio Series - Multi-protocol Edition (Enterprise Profile)","f573f209-b7fb-b261-671a-d7cf624cc812":"Excelsecu eSecu FIDO2 PRO+ Security Key","005b20e1-f146-4b87-8f3a-36848ff60ea6":"SECORA ID V2 by Infineon Pay Edition M","6e24d385-004a-16a0-7bfe-efd963845b34":"Ledger Stax FIDO2 Authenticator","ee882879-721c-4913-9775-3dfcce97072a":"YubiKey 5 Series","8876631b-d4a0-427f-5773-0ec71c9e0279":"Solo Secp256R1 FIDO2 CTAP2 Authenticator","fec067a1-f1d0-4c5e-b4c0-cc3237475461":"KX701 SmartToken FIDO","30b5035e-d297-4ff1-b00b-addc96ba6a98":"OneSpan DIGIPASS FX1 BIO","b267239b-954f-4041-a01b-ee4f33c145b6":"authenton1 - CTAP2.1","b50d5e0a-7f81-4959-9b12-f45407407503":"IDPrime 3940 FIDO","8c97a730-3f7b-41a6-87d6-1e9b62bda6f0":"FT-JCOS FIDO Fingerprint Card","99bf4610-ec26-4252-b31f-7380ccd59db5":"ZTPass SmartAuth","a1f52be5-dfab-4364-b51c-2bd496b14a56":"OCTATCO EzFinger2 FIDO2 AUTHENTICATOR","c3479970-e58a-4f70-836f-853bf42fb063":"YubiKey 5 Series with Lightning (Enterprise Profile)","0f00cc22-4640-41e7-9585-384ec73ffe9b":"Taglio CTAP2.1 BIO","ff4dac45-ede8-4ec2-aced-cf66103f4335":"YubiKey 5 Series","ba86dc56-635f-4141-aef6-00227b1b9af6":"TruU Windows Authenticator","3e078ffd-4c54-4586-8baa-a77da113aec5":"Hideez Key 3 FIDO2","fc5ca237-69a0-4f3c-afe4-1ebc66def6df":"Clife Key 2","ec31b4cc-2acc-4b8e-9c01-bade00ccbe26":"KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2 Authenticator","5d629218-d3a5-11ed-afa1-0242ac120002":"Swissbit iShield Key Pro","bb878d7b-cf54-4784-b390-357030497043":"TruU FIDO2 Authenticator","d41f5a69-b817-4144-a13c-9ebd6d9254d6":"ATKey.Card CTAP2.0","e86addcd-7711-47e5-b42a-c18257b0bf61":"IDCore 3121 Fido","39502df1-646d-4e31-81a1-2ef68b324678":"USB GoldKey Security Token","8108bdcd-8483-46b3-b3ce-359f8190325e":"SECORA ID V2 by Infineon Enterprise Edition","b113a455-cfb6-4c17-8cba-cd952feb7d48":"eToken FIDO NFC","95442b2e-f15e-4def-b270-efb106facb4e":"eWBM eFA310 FIDO2 Authenticator","dda9aa35-aaf1-4d3c-b6db-7902fd7dbbbf":"IDEMIA SOLVO Fly 80 R3 FIDO Card c","cdbdaea2-c415-5073-50f7-c04e968640b6":"Excelsecu eSecu FIDO2 Security Key","3aa78eb1-ddd8-46a8-a821-8f8ec57a7bd5":"YubiKey 5 CCN Series with NFC","bc2fe499-0d8e-4ffe-96f3-94a82840cf8c":"OCTATCO EzQuant FIDO2 AUTHENTICATOR","eb3b131e-59dc-536a-d176-cb7306da10f5":"ellipticSecure MIRkey USB Authenticator","3fd410dc-8ab7-4b86-a1cb-c7174620b2dc":"IDEMIA SOLVO Fly 80 R1 FIDO Card Draft","c09b3399-4a3d-306c-7bdc-967fef47241f":"Giesecke+Devrient StarSign FIDO Card 2.1","a6c5f5d8-2ad0-48b6-8257-e502c8970931":"eToken FIDO NFC Enterprise","e400ef8c-711d-4692-af46-7f2cf7da23ad":"Swissbit iShield Key 2 Enterprise","87c13177-85d6-40ac-8c61-fe7ab3de9dfb":"HID Crescendo Key V3","1c086528-58d5-f211-823c-356786e36140":"Atos CardOS FIDO2","77010bd7-212a-4fc9-b236-d2ca5e9d4084":"Feitian BioPass FIDO2 Authenticator","3b3faa7b-2c56-4489-bcd3-53b83ee75768":"SECORA Connect SLS21 D1 FIDO 2.1 v1.0 by Infineon - Enterprise Edition","d94a29d9-52dd-4247-9c2d-8b818b610389":"VeriMark Guard Fingerprint Key","7b96457d-e3cd-432b-9ceb-c9fdd7ef7432":"YubiKey 5 FIPS Series with Lightning","7991798a-a7f3-487f-98c0-3faf7a458a04":"HID Crescendo Key V3","833b721a-ff5f-4d00-bb2e-bdda3ec01e29":"Feitian ePass FIDO2 Authenticator","c89674e3-a765-4b07-888a-7c086fbdf04b":"StarSign FIDO Card","a11a5faa-9f32-4b8c-8c5d-2f7d13e8c942":"AliasVault","ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4":"Google Password Manager","adce0002-35bc-c60a-648b-0b25f1f05503":"Chrome on Mac","dd4ec289-e01d-41c9-bb89-70fa845d4bf2":"iCloud Keychain (Managed)","531126d6-e717-415c-9320-3d9aa6981239":"Dashlane","bada5566-a7aa-401f-bd96-45619a55120d":"1Password","b84e4048-15dc-4dd0-8640-f4f60813c8af":"NordPass","0ea242b4-43c4-4a1b-8b17-dd6d0b6baec6":"Keeper","891494da-2c90-4d31-a9cd-4eab0aed1309":"Sésame","f3809540-7f14-49c1-a8b3-8f813b225541":"Enpass","b5397666-4885-aa6b-cebf-e52262a439a2":"Chromium Browser","771b48fd-d3d4-4f74-9232-fc157ab0507a":"Edge on Mac","d548826e-79b4-db40-a3d8-11116f7e8349":"Bitwarden","fbfc3007-154e-4ecc-8c0b-6e020557d7bd":"Apple Passwords","66a0ccb3-bd6a-191f-ee06-e375c50b9846":"Thales Bio iOS SDK","8836336a-f590-0921-301d-46427531eee6":"Thales Bio Android SDK","cd69adb5-3c7a-deb9-3177-6800ea6cb72a":"Thales PIN Android SDK","17290f1e-c212-34d0-1423-365d729f09d9":"Thales PIN iOS SDK","50726f74-6f6e-5061-7373-50726f746f6e":"Proton Pass","fdb141b2-5d84-443e-8a35-4698c205a502":"KeePassXC","eaecdef2-1c31-5634-8639-f1cbd9c00a08":"KeePassDX","9addb28c-b46f-4402-808f-019651441ff3":"KeePassPasskey","bfc748bb-3429-4faa-b9f9-7cfa9f3b76d0":"iPasswords","b35a26b2-8f6e-4697-ab1d-d44db4da28c6":"Zoho Vault","b78a0a55-6ef8-d246-a042-ba0f6d55050c":"LastPass","de503f9c-21a4-4f76-b4b7-558eb55c6f89":"Devolutions","22248c4c-7a12-46e2-9a41-44291b373a4d":"LogMeOnce","a10c6dd9-465e-4226-8198-c7c44b91c555":"Kaspersky Password Manager","d350af52-0351-4ba2-acd3-dfeeadc3f764":"pwSafe","d3452668-01fd-4c12-926c-83a4204853aa":"Microsoft Password Manager","6d212b28-a2c1-4638-b375-5932070f62e9":"initial","d49b2120-b865-4191-8cea-be84a52b0485":"Heimlane Vault","d9be9d39-e6a6-4c28-a581-32b044d986e4":"Sticky Password Manager","70617373-7761-6c6c-6669-646f32303236":"Passwall","c9cadfc9-89a9-489e-a25a-c7e86a4d5f15":"Burp Suite Navigation Recorder","fa37f553-f9b6-4adb-ac53-8bbb57ebdf0d":"Norton Password Manager","a4a2d88e-9796-4356-9164-e2a5a8bd019c":"Avast Password Manager","e7db2bd3-f2fe-4d71-ad78-7e7aa166cfd1":"Avira Password Manager","6bb49926-160a-4306-a100-4eb39ba6ac45":"AVG Password Manager","da583154-ce16-4cdf-9fe6-1dba788c0998":"Hey Be Safe","d2717a32-9851-48a8-9961-b264c97a411a":"Fenko Vault","65c97700-f5ef-4d5c-8a42-f30e45ac94b7":"Royal Vault","5ca471bb-a56d-46ad-a496-67e70e9ed9fb":"Parcel","45e3057e-b2f9-48ed-912f-9b901e153b16":"Uniqkey","87f5ec51-f721-4feb-9fe4-be18c4971894":"PassCard","477b05cd-7f78-4fe7-b629-27247f296138":"WALLIX Vault","53e7a7a5-e75f-4d3d-9483-12fc779cdf23":"Password Depot","cb6f6666-38ea-4873-9161-ff456a82d316":"iPass Secure Auth","9f8a3b2c-1d4e-4f6a-8b0c-2e1d3c4b5a69":"U2 Secured"} +{ + "005b20e1-f146-4b87-8f3a-36848ff60ea6": { + "name": "SECORA ID V2 by Infineon Pay Edition M" + }, + "0076631b-d4a0-427f-5773-0ec71c9e0279": { + "name": "HYPR FIDO2 Authenticator" + }, + "019614a3-2703-7e35-a453-285fd06c5d24": { + "name": "ATLKey Authenticator" + }, + "03012cb7-4fb2-42e7-9e8d-a81f10e2a5e9": { + "name": "YubiKey 5 Series with Lightning (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "04a8fcf2-19c1-457b-911e-69219f17583f": { + "name": "Thales PAY GFCX13 authenticator" + }, + "050dd0bc-ff20-4265-8d5d-305c4b215192": { + "name": "eToken Fusion FIPS" + }, + "07a9f89c-6407-4594-9d56-621d5f1e358b": { + "name": "NXP Semiconductros FIDO2 Conformance Testing CTAP2 Authenticator" + }, + "08987058-cadc-4b81-b6e1-30de50dcbe96": { + "name": "Windows Hello", + "icon_light": "e63a433d41e3bbd1.svg" + }, + "092277e5-8437-46b5-b911-ea64b294acb7": { + "name": "Taglio CTAP2.1 CS" + }, + "09591fc6-9811-48f7-8f57-b9f23df6413f": { + "name": "Pone Biometrics OFFPAD Authenticator" + }, + "09619fbf-d75e-4a62-be1d-fe4d240864ae": { + "name": "VeriMark(TM) Guard 2.1 Fingerprint Security Key" + }, + "0a357157-9b18-4c8a-920e-d156e972b2f8": { + "name": "YubiKey 5 Series (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "0acf3011-bc60-f375-fb53-6f05f43154e0": { + "name": "Nymi FIDO2 Authenticator" + }, + "0b8b05a4-ebd4-4b0b-8f5f-33d7b6e606ab": { + "name": "HID Crescendo 4000" + }, + "0bb43545-fd2c-4185-87dd-feb0b2916ace": { + "name": "Security Key NFC by Yubico - Enterprise Edition" + }, + "0d9b2e56-566b-c393-2940-f821b7f15d6d": { + "name": "Excelsecu eSecu FIDO2 Pro Security Key" + }, + "0db01cd6-5618-455b-bb46-1ec203d3213e": { + "name": "GoldKey Security Token" + }, + "0ea242b4-43c4-4a1b-8b17-dd6d0b6baec6": { + "name": "Keeper", + "icon_light": "54c30775685066bc.svg" + }, + "0ebd9f2c-f685-441c-8c3e-a02a234a840a": { + "name": "YubiKey 5 Series with NFC Enhanced PIN (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "0f00cc22-4640-41e7-9585-384ec73ffe9b": { + "name": "Taglio CTAP2.1 BIO" + }, + "0f083f18-4105-43a8-ad69-24e812e38141": { + "name": "Security Key Series with NFC (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "0fbb74b5-f1ac-4f14-a0f1-ec39b5edfdae": { + "name": "Thales PAY GFCX19 authenticator" + }, + "10c70715-2a9a-4de1-b0aa-3cff6d496d39": { + "name": "eToken Fusion NFC FIPS" + }, + "1105e4ed-af1d-02ff-ffff-ffffffffffff": { + "name": "Egomet FIDO2 Authenticator for Android" + }, + "11544c3c-3693-40ba-9dbb-3b8d2b977988": { + "name": "Thales PAY GFCX20.1 authenticator" + }, + "12755c32-8ad1-46eb-881c-e0b38d848b09": { + "name": "Feitian ePass FIDO Authenticator (CTAP2.1, CTAP2.0, U2F)" + }, + "12ded745-4bed-47d4-abaa-e713f51d6393": { + "name": "Feitian AllinOne FIDO2 Authenticator" + }, + "13ac47cf-1d78-4fd5-9060-aedaabacf826": { + "name": "HID Crescendo Key V3 - Enterprise Edition" + }, + "146e77ef-11eb-4423-b847-ce77864e9411": { + "name": "eToken Fusion NFC PIV" + }, + "149a2021-8ef6-4133-96b8-81f8d5b7f1f5": { + "name": "Security Key by Yubico with NFC" + }, + "17290f1e-c212-34d0-1423-365d729f09d9": { + "name": "Thales PIN iOS SDK", + "icon_light": "5cacab8124984715.svg", + "icon_dark": "fe2583b9176a3347.svg" + }, + "175cd298-83d2-4a26-b637-313c07a6434e": { + "name": "Chunghwa Telecom FIDO2 Smart Card Authenticator" + }, + "18852056-063b-4042-9814-7d0d383081f9": { + "name": "SECORA ID Key S USB by Infineon Enterprise Edition" + }, + "19083c3d-8383-4b18-bc03-8f1c9ab2fd1b": { + "name": "YubiKey 5 Series" + }, + "19bca99b-7c09-44fe-a969-8cba45764542": { + "name": "HID Crescendo Key V3 FIPS" + }, + "1ac71f64-468d-4fe0-bef1-0e5f2f551f18": { + "name": "YubiKey 5 Series with NFC (Enterprise Profile)" + }, + "1c086528-58d5-f211-823c-356786e36140": { + "name": "Atos CardOS FIDO2" + }, + "1d1b4e33-76a1-47fb-97a0-14b10d0933f1": { + "name": "Cryptnox FIDO2.1" + }, + "1d8cac46-47a1-3386-af50-e88ae46fe802": { + "name": "Ledger Flex FIDO2 Authenticator" + }, + "1e906e14-77af-46bc-ae9f-fe6ef18257e4": { + "name": "VeridiumID Passkey iOS SDK" + }, + "1f8e43df-71ff-e11d-bea3-c4ee7003b232": { + "name": "Thetis Pro FIDO2 Key" + }, + "20ac7a17-c814-4833-93fe-539f0d5e3389": { + "name": "YubiKey 5 Series (Enterprise Profile)" + }, + "20f0be98-9af9-986a-4b42-8eca4acb28e4": { + "name": "Excelsecu eSecu FIDO2 Fingerprint Security Key" + }, + "2194b428-9397-4046-8f39-007a1605a482": { + "name": "IDPrime 931 Fido" + }, + "22248c4c-7a12-46e2-9a41-44291b373a4d": { + "name": "LogMeOnce", + "icon_light": "392d7b1382ef234c.svg", + "icon_dark": "3ddddea0f68ee3b1.svg" + }, + "22682ee5-4f0e-4c19-be3e-797d5770ebfe": { + "name": "Precision InnaIT Key FIDO 2 Level 2 certified" + }, + "23195a52-62d9-40fa-8ee5-23b173f4fb52": { + "name": "Hyper FIDO Pro NFC" + }, + "23315ad0-6aca-4ba1-952e-f044f1e36976": { + "name": "Clife Key 2 NFC" + }, + "234cd403-35a2-4cc2-8015-77ea280c77f5": { + "name": "Feitian ePass FIDO2-NFC Series (CTAP2.1, CTAP2.0, U2F)" + }, + "23786452-f02d-4344-87ed-aaf703726881": { + "name": "SafeNet eToken Fusion CC" + }, + "238ab2f5-b57f-4917-b3c6-3d3c6c0c350f": { + "name": "FEITIAN FT-JCOS BioCard" + }, + "24083bcb-3034-4867-99de-a3b52e1d426a": { + "name": "Enterprise Security Key Series with NFC (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "24673149-6c86-42e7-98d9-433fb5b73296": { + "name": "YubiKey 5 Series with Lightning", + "icon_light": "7db3534fd5258565.svg" + }, + "2588ae83-5a3b-4536-b8de-5e540200d191": { + "name": "Dapple Authenticator from Dapple Security Inc." + }, + "260e3021-482d-442d-838c-7edfbe153b7e": { + "name": "Feitian ePass FIDO2-NFC Plus Authenticator" + }, + "2772ce93-eb4b-4090-8b73-330f48477d73": { + "name": "Security Key NFC by Yubico - Enterprise Edition Preview" + }, + "2a55aee6-27cb-42c0-bc6e-04efe999e88a": { + "name": "HID Crescendo 4000" + }, + "2bff89f2-323a-48fc-b7c8-9ff7fe87c07e": { + "name": "Feitian BioPass FIDO2 Pro (Enterprise Profile)" + }, + "2c0df832-92de-4be1-8412-88a8f074df4a": { + "name": "Feitian FIDO Smart Card" + }, + "2c2aeed8-8174-4159-814b-486e92a261d0": { + "name": "NEOWAVE WINKEO V2.0" + }, + "2cd2f727-f6ca-44da-8f48-5c2e5da000a2": { + "name": "Nitrokey 3 AM" + }, + "2d3bec26-15ee-4f5d-88b2-53622490270b": { + "name": "HID Crescendo Key V2" + }, + "2fc0579f-8113-47ea-b116-bb5a8db9202a": { + "name": "YubiKey 5 Series with NFC" + }, + "2ffd6452-01da-471f-821b-ea4bf6c8676a": { + "name": "IDPrime 941 Fido" + }, + "30b5035e-d297-4fc1-b00b-addc96ba6a97": { + "name": "OneSpan FIDO Touch" + }, + "30b5035e-d297-4ff1-010b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX1a" + }, + "30b5035e-d297-4ff1-020b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX1-C" + }, + "30b5035e-d297-4ff1-b00b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX1 BIO" + }, + "30b5035e-d297-4ff2-010b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX2-A" + }, + "30b5035e-d297-4ff7-010b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX7-B" + }, + "30b5035e-d297-4ff7-020b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX7" + }, + "30b5035e-d297-4ff7-030b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX7-C" + }, + "30b5035e-d297-4ff7-b00b-addc96ba6a98": { + "name": "OneSpan DIGIPASS FX7" + }, + "3124e301-f14e-4e38-876d-fbeeb090e7bf": { + "name": "YubiKey 5 Series with Lightning Preview" + }, + "31c3f7ff-bf15-4327-83ec-9336abcbcd34": { + "name": "WinMagic FIDO Eazy - Software" + }, + "33d6d7d0-279f-4ef3-96b3-2d3282f4bde6": { + "name": "Thales eToken Fusion BIO Enterprise" + }, + "341e4da9-3c2e-8103-5a9f-aad887135200": { + "name": "Ledger Nano S FIDO2 Authenticator" + }, + "34744913-4f57-4e6e-a527-e9ec3c4b94e6": { + "name": "YubiKey Bio Series - Multi-protocol Edition", + "icon_light": "7db3534fd5258565.svg" + }, + "34f5766d-1536-4a24-9033-0e294e510fb0": { + "name": "YubiKey 5 Series with NFC Preview" + }, + "357f2718-434f-4124-8a58-7e28c5e4a2fc": { + "name": "Deepnet SafeKey/Classic (NFC)" + }, + "361a3082-0278-4583-a16f-72a527f973e4": { + "name": "eWBM eFA500 FIDO2 Authenticator" + }, + "3789da91-f943-46bc-95c3-50ea2012f03a": { + "name": "NEOWAVE Winkeo FIDO2" + }, + "39502df1-646d-4e31-81a1-2ef68b324678": { + "name": "USB GoldKey Security Token" + }, + "39589099-9a75-49fc-afaa-801ca211c62a": { + "name": "Feitian ePass FIDO-NFC (Enterprise Profile) (CTAP2.1, CTAP2.0, U2F)" + }, + "39a5647e-1853-446c-a1f6-a79bae9f5bc7": { + "name": "IDmelon", + "icon_light": "9f46d84e118605ca.svg" + }, + "3a662962-c6d4-4023-bebb-98ae92e78e20": { + "name": "YubiKey 5 FIPS Series with Lightning (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "3aa78eb1-ddd8-46a8-a821-8f8ec57a7bd5": { + "name": "YubiKey 5 CCN Series with NFC", + "icon_light": "7db3534fd5258565.svg" + }, + "3b1adb99-0dfe-46fd-90b8-7f7614a4de2a": { + "name": "GoTrust Idem Key" + }, + "3b24bf49-1d45-4484-a917-13175df0867b": { + "name": "YubiKey 5 Series with Lightning (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "3b3faa7b-2c56-4489-bcd3-53b83ee75768": { + "name": "SECORA Connect SLS21 D1 FIDO 2.1 v1.0 by Infineon - Enterprise Edition" + }, + "3e078ffd-4c54-4586-8baa-a77da113aec5": { + "name": "Hideez Key 3 FIDO2" + }, + "3e22415d-7fdf-4ea4-8a0c-dd60c4249b9d": { + "name": "Feitian iePass FIDO Authenticator" + }, + "3e9db280-256a-4e17-b08e-19d79e9be166": { + "name": "SECORA ID V2 by Infineon Pay Edition" + }, + "3ec9c8d3-a5a7-415b-a7b5-f1d606368d3f": { + "name": "YubiKey 5 CCN Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "3f59672f-20aa-4afe-b6f4-7e5e916b6d98": { + "name": "Arculus FIDO 2.1 Key Card [P71]" + }, + "3fd410dc-8ab7-4b86-a1cb-c7174620b2dc": { + "name": "IDEMIA SOLVO Fly 80 R1 FIDO Card Draft" + }, + "41e39911-c669-4811-b860-c6ad0b411b96": { + "name": "YubiKey 5 Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "42b4fb4a-2866-43b2-9bf7-6c6669c2e5d3": { + "name": "Google Titan Security Key v2" + }, + "42df17de-06ba-4177-a2bb-6701be1380d6": { + "name": "Feitian BioPass FIDO2 Plus Authenticator" + }, + "454e5346-4944-4ffd-6c93-8e9267193e9a": { + "name": "Ensurity ThinC" + }, + "454e5346-4944-4ffd-6c93-8e9267193e9b": { + "name": "Ensurity AUTH BioPro" + }, + "4599062e-6926-4fe7-9566-9e8fb1aedaa0": { + "name": "YubiKey 5 Series (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "45e3057e-b2f9-48ed-912f-9b901e153b16": { + "name": "Uniqkey", + "icon_light": "cbc4ebc69a8d3188.svg", + "icon_dark": "22fc41ef278b65de.svg" + }, + "46544d5d-8f5d-4db4-89ac-ea8977073fff": { + "name": "Foongtone FIDO Authenticator" + }, + "477b05cd-7f78-4fe7-b629-27247f296138": { + "name": "WALLIX Vault", + "icon_light": "56f8d0a7f2afba25.svg" + }, + "47ab2fb4-66ac-4184-9ae1-86be814012d5": { + "name": "Security Key NFC by Yubico - Enterprise Edition" + }, + "489ff376-b48d-6640-bb69-782a860ca795": { + "name": "Mettlesemi Vishwaas Eagle Authenticator using FIDO2" + }, + "49a15c1c-3f63-3f51-23a7-b9e00096edd1": { + "name": "IDEX CTAP2.1 Biometrics" + }, + "4b3f8944-d4f2-4d21-bb19-764a986ec160": { + "name": "KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "4b89f401-464e-4745-a520-486ddfc5d80e": { + "name": "IIST FIDO2 Authenticator" + }, + "4c0cf95d-2f40-43b5-ba42-4c83a11c04ba": { + "name": "Feitian BioPass FIDO2 Pro Authenticator" + }, + "4c50ff10-1057-4fc6-b8ed-43a529530c3c": { + "name": "ImproveID Authenticator" + }, + "4d41190c-7beb-4a84-8018-adf265a6352d": { + "name": "Thales IDPrime FIDO Bio" + }, + "4e2ddbc2-2687-4709-8551-cb66c9776bfe": { + "name": "SECORA ID V2 FIDO2.1 L1" + }, + "4e768f2c-5fab-48b3-b300-220eb487752b": { + "name": "Hideez Key 4 FIDO2 SDK" + }, + "4fc84f16-2545-4e53-b8fc-7bf4d7282a10": { + "name": "YubiKey 5 CCN Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "504d7149-4e4c-3841-4555-55445a677357": { + "name": "WiSECURE AuthTron USB FIDO2 Authenticator" + }, + "50726f74-6f6e-5061-7373-50726f746f6e": { + "name": "Proton Pass", + "icon_light": "a2983af5687c5c09.svg" + }, + "50a45b0c-80e7-f944-bf29-f552bfa2e048": { + "name": "ACS FIDO Authenticator" + }, + "50cbf15a-238c-4457-8f16-812c43bf3c49": { + "name": "Ensurity AUTH TouchPro" + }, + "516d3969-5a57-5651-5958-4e7a49434167": { + "name": "SmartDisplayer BobeePass FIDO2 Authenticator" + }, + "51787637-8ab8-460c-9302-de0b853d4ffb": { + "name": "SpearID FIDO2 Standard" + }, + "522a3f91-5f5d-480d-be37-6cecfad5a27b": { + "name": "Precision InnaIT Key FIDO 2 Level 2 certified" + }, + "524de2de-982f-49b4-a769-2b5e3b73ad79": { + "name": "YubiKey 5 Series (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "531126d6-e717-415c-9320-3d9aa6981239": { + "name": "Dashlane", + "icon_light": "a9773b88cb8d368a.svg", + "icon_dark": "905e0b26ed90f80c.svg" + }, + "53334693-4b3f-4198-8857-53772de2ab65": { + "name": "Precision InnaIT Key FIDO 2 Level 2 certified" + }, + "53414d53-554e-4700-0000-000000000000": { + "name": "Samsung Pass", + "icon_light": "d6098dee8bf5800c.svg" + }, + "5343502d-5343-5343-6172-644649444f32": { + "name": "ESS Smart Card Inc. Authenticator" + }, + "53e7a7a5-e75f-4d3d-9483-12fc779cdf23": { + "name": "Password Depot", + "icon_light": "8bae707e5f61c50a.svg", + "icon_dark": "a72a9761e0b6dd4b.svg" + }, + "54d9fee8-e621-4291-8b18-7157b99c5bec": { + "name": "HID Crescendo Enabled" + }, + "55fd881f-40ba-4eaf-8435-42c5fed08b76": { + "name": "SECORA ID V2 by Infineon Consumer Edition" + }, + "560a780c-b6ae-4f03-b110-082f856425b4": { + "name": "KQC QuKey Bio FIDO2 Authenticator" + }, + "5626bed4-e756-430b-a7ff-ca78c8b12738": { + "name": "VALMIDO PRO FIDO" + }, + "57235694-51a5-4a4d-a81a-f42185df6502": { + "name": "SHALO AUTH" + }, + "5753362b-4e6b-6345-7b2f-255438404c75": { + "name": "WiSECURE Blentity FIDO2 Authenticator" + }, + "57f7de54-c807-4eab-b1c6-1c9be7984e92": { + "name": "YubiKey 5 FIPS Series", + "icon_light": "7db3534fd5258565.svg" + }, + "58276709-bb4b-4bb3-baf1-60eea99282a7": { + "name": "YubiKey Bio Series - Multi-protocol Edition 1VDJSN", + "icon_light": "7db3534fd5258565.svg" + }, + "58b44d0b-0a7c-f33a-fd48-f7153c871352": { + "name": "Ledger Nano S Plus FIDO2 Authenticator" + }, + "59f85fe7-faa5-4c92-9f52-697b9d4d5473": { + "name": "RSA Authenticator 4 for Android" + }, + "5b0e46ba-db02-44ac-b979-ca9b84f5e335": { + "name": "YubiKey 5 FIPS Series with Lightning Preview" + }, + "5ca1ab1e-1337-fa57-f1d0-a117e71ca702": { + "name": "Allthenticator iOS App: roaming BLE FIDO2 Allthenticator for Windows, Mac, Linux, and Allthenticate door readers" + }, + "5ca1ab1e-fa57-1337-f1d0-a117371ca702": { + "name": "Allthenticator Android App: roaming BLE FIDO2 Allthenticator for Windows, Mac, Linux, and Allthenticate door readers" + }, + "5ca471bb-a56d-46ad-a496-67e70e9ed9fb": { + "name": "Parcel", + "icon_light": "3256d3e03d87ce0a.svg" + }, + "5d629218-d3a5-11ed-afa1-0242ac120002": { + "name": "Swissbit iShield Key Pro" + }, + "5df66f62-5b47-43d3-aa1d-a6e31c8dbeb5": { + "name": "Securitag Assembly Group FIDO Authenticator NFC" + }, + "5e264d9d-28ef-4d34-95b4-5941e7a4faa8": { + "name": "Ideem ZSM FIDO2 Authenticator" + }, + "5ea308b2-7ac7-48b9-ac09-7e2da9015f8c": { + "name": "Veridium Android SDK" + }, + "5eaff75a-dd43-451f-af9f-87c9eeae293e": { + "name": "Swissbit iShield Key 2 FIPS Enterprise" + }, + "5fdb81b8-53f0-4967-a881-f5ec26fe4d18": { + "name": "VinCSS FIDO2 Authenticator" + }, + "6002f033-3c07-ce3e-d0f7-0ffe5ed42543": { + "name": "Excelsecu eSecu FIDO2 Fingerprint Key" + }, + "6028b017-b1d4-4c02-b4b3-afcdafc96bb2": { + "name": "Windows Hello", + "icon_light": "e63a433d41e3bbd1.svg" + }, + "61250591-b2bc-4456-b719-0b17be90bb30": { + "name": "eWBM eFPA FIDO2 Authenticator" + }, + "6169eb16-f87a-42d8-978d-e1ac0c3f319f": { + "name": "GoTrust Idem Card" + }, + "62e54e98-c209-4df3-b692-de71bb6a8528": { + "name": "YubiKey 5 FIPS Series with NFC Preview" + }, + "65c97700-f5ef-4d5c-8a42-f30e45ac94b7": { + "name": "Royal Vault", + "icon_light": "b9815d4fd9eb10a7.svg", + "icon_dark": "faac7e28bcf9ba73.svg" + }, + "662ef48a-95e2-4aaa-a6c1-5b9c40375824": { + "name": "YubiKey 5 Series with NFC - Enhanced PIN", + "icon_light": "7db3534fd5258565.svg" + }, + "664d9f67-84a2-412a-9ff7-b4f7d8ee6d05": { + "name": "OpenSK authenticator" + }, + "66a0ccb3-bd6a-191f-ee06-e375c50b9846": { + "name": "Thales Bio iOS SDK", + "icon_light": "5cacab8124984715.svg", + "icon_dark": "fe2583b9176a3347.svg" + }, + "6832d205-75f2-44c7-a864-e868c796d06e": { + "name": "Precision InnaIT Key FIDO 2 Level 2 certified" + }, + "686de81e-fff2-41c1-bb83-2723aaf3e913": { + "name": "IIST SASE USB KEY 1" + }, + "692db549-7ae5-44d5-a1e5-dd20a493b723": { + "name": "HID Crescendo Key" + }, + "69700f79-d1fb-472e-bd9b-a3a3b9a9eda0": { + "name": "Pone Biometrics OFFPAD Authenticator" + }, + "6999180d-630c-442d-b8f7-424b90a43fae": { + "name": "Hyper FIDO Pro (CTAP2.1, CTAP2.0, U2F)" + }, + "69e7c36f-f2f6-9e0d-07a6-bcc243262e6b": { + "name": "OneKey FIDO2 Authenticator" + }, + "6ab56fad-881f-4a43-acb2-0be065924522": { + "name": "YubiKey 5 Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "6bb49926-160a-4306-a100-4eb39ba6ac45": { + "name": "AVG Password Manager", + "icon_light": "e8ae0a4206de8b1f.svg" + }, + "6d212b28-a2c1-4638-b375-5932070f62e9": { + "name": "initial", + "icon_light": "0279c1253367b259.svg" + }, + "6d44ba9b-f6ec-2e49-b930-0c8fe920cb73": { + "name": "Security Key by Yubico with NFC" + }, + "6d4aa745-dad5-40c4-b9b4-6a252fcee70f": { + "name": "GoTrust Cyber Key" + }, + "6dae43be-af9c-417b-8b9f-1b611168ec60": { + "name": "Dapple Authenticator from Dapple Security Inc." + }, + "6e24d385-004a-16a0-7bfe-efd963845b34": { + "name": "Ledger Stax FIDO2 Authenticator" + }, + "6e34341a-88c7-483d-b777-a425c355be93": { + "name": "WebComm OETHenticator" + }, + "6e8d1eae-8d40-4c25-bcf8-4633959afc71": { + "name": "Veridium iOS SDK" + }, + "6ec5cff2-a0f9-4169-945b-f33b563f7b99": { + "name": "YubiKey Bio Series - Multi-protocol Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "70617373-7761-6c6c-6669-646f32303236": { + "name": "Passwall" + }, + "70e7c36f-f2f6-9e0d-07a6-bcc243262e6b": { + "name": "OneKey FIDO2 Bluetooth Authenticator" + }, + "72a2b5b1-95a5-4df9-a881-4192aff4f72e": { + "name": "GoTrust Idem Key mini" + }, + "72c6b72d-8512-4c66-8359-9d3d10d9222f": { + "name": "Security Key NFC by Yubico - Enterprise Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "73402251-f2a8-4f03-873e-3cb6db604b03": { + "name": "uTrust FIDO2 Security Key" + }, + "73bb0cd4-e502-49b8-9c6f-b59445bf720b": { + "name": "YubiKey 5 FIPS Series" + }, + "7409272d-1ff9-4e10-9fc9-ac0019c124fd": { + "name": "YubiKey Bio Series - FIDO Edition", + "icon_light": "7db3534fd5258565.svg" + }, + "74820b05-a6c9-40f9-8fb0-9f86aca93998": { + "name": "SafeNet eToken Fusion" + }, + "760eda36-00aa-4d29-855b-4012a182cdeb": { + "name": "Security Key NFC by Yubico Preview" + }, + "76692dc1-c56a-48d9-8e7d-31b5ced430ac": { + "name": "VeriMark NFC+ USB-A Security Key" + }, + "77010bd7-212a-4fc9-b236-d2ca5e9d4084": { + "name": "Feitian BioPass FIDO2 Authenticator" + }, + "771b48fd-d3d4-4f74-9232-fc157ab0507a": { + "name": "Edge on Mac", + "icon_light": "75a96840f046f6f0.svg" + }, + "773c30d9-5919-4e96-a4f5-db65e95cf890": { + "name": "GSTAG OAK FIDO2 Authenticator" + }, + "7787a482-13e8-4784-8a06-c7ed49a7aaf4": { + "name": "Swissbit iShield Key 2" + }, + "78ba3993-d784-4f44-8d6e-cc0a8ad5230e": { + "name": "Feitian ePass FIDO-NFC(CTAP2.1, CTAP2.0, U2F)" + }, + "7991798a-a7f3-487f-98c0-3faf7a458a04": { + "name": "HID Crescendo Key V3" + }, + "79f3c8ba-9e35-484b-8f47-53a5a0f5c630": { + "name": "YubiKey 5 FIPS Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "7a53c643-9dec-4219-b3a4-f9d24aca4e12": { + "name": "G+D StarKey FIDO2-NFC" + }, + "7b96457d-e3cd-432b-9ceb-c9fdd7ef7432": { + "name": "YubiKey 5 FIPS Series with Lightning", + "icon_light": "7db3534fd5258565.svg" + }, + "7d1351a6-e097-4852-b8bf-c9ac5c9ce4a3": { + "name": "YubiKey Bio Series - Multi-protocol Edition" + }, + "7d2afadd-bf6b-44a2-a66b-e831fceb8eff": { + "name": "Taglio CTAP2.1 EP" + }, + "7dab85a5-d16d-4eaf-a7ef-4c1385b151c5": { + "name": "YubiKey 5 Series with NFC (Consumer Profile) KVZR57-2", + "icon_light": "7db3534fd5258565.svg" + }, + "7e3f3d30-3557-4442-bdae-139312178b39": { + "name": "RSA DS100" + }, + "8108bdcd-8483-46b3-b3ce-359f8190325e": { + "name": "SECORA ID V2 by Infineon Enterprise Edition" + }, + "817cdab8-0d51-4de1-a821-e25b88519cf3": { + "name": "Swissbit iShield Key 2 FIPS" + }, + "820d89ed-d65a-409e-85cb-f73f0578f82a": { + "name": "IDmelon Authenticator" + }, + "82b0a720-127a-4788-b56d-d1d4b2d82eac": { + "name": "ID-One Key" + }, + "833b721a-ff5f-4d00-bb2e-bdda3ec01e29": { + "name": "Feitian ePass FIDO2 Authenticator" + }, + "83c47309-aabb-4108-8470-8be838b573cb": { + "name": "YubiKey Bio Series - FIDO Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "85203421-48f9-4355-9bc8-8a53846e5083": { + "name": "YubiKey 5 FIPS Series with Lightning" + }, + "8681a073-5f50-4d52-bce4-e21658d207b3": { + "name": "RSA Authenticator 4 for iOS" + }, + "8791f7dc-418b-4510-bbf5-3baf30715324": { + "name": "Virtual FIDO2 authenticator for Linux-based systems" + }, + "87c13177-85d6-40ac-8c61-fe7ab3de9dfb": { + "name": "HID Crescendo Key V3" + }, + "87dbc5a1-4c94-4dc8-8a47-97d800fd1f3c": { + "name": "eWBM eFA320 FIDO2 Authenticator" + }, + "87f5ec51-f721-4feb-9fe4-be18c4971894": { + "name": "PassCard", + "icon_light": "5f7a884ad381ceaa.svg" + }, + "882adaf5-3aa9-4708-8e7d-3957103775b4": { + "name": "T-Shield TrustSec FIDO2 Bio and client PIN version" + }, + "8836336a-f590-0921-301d-46427531eee6": { + "name": "Thales Bio Android SDK", + "icon_light": "5cacab8124984715.svg", + "icon_dark": "fe2583b9176a3347.svg" + }, + "8876631b-d4a0-427f-5773-0ec71c9e0279": { + "name": "Solo Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "88bbd2f0-342a-42e7-9729-dd158be5407a": { + "name": "Precision InnaIT Key FIDO 2 Level 2 certified" + }, + "891494da-2c90-4d31-a9cd-4eab0aed1309": { + "name": "Sésame", + "icon_light": "382fbdca2eb19cec.svg" + }, + "8976631b-d4a0-427f-5773-0ec71c9e0279": { + "name": "Solo Tap Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "89b19028-256b-4025-8872-255358d950e4": { + "name": "Sentry Enterprises CTAP2 Authenticator" + }, + "8c39ee86-7f9a-4a95-9ba3-f6b097e5c2ee": { + "name": "YubiKey Bio Series - FIDO Edition (Enterprise Profile)" + }, + "8c97a730-3f7b-41a6-87d6-1e9b62bda6f0": { + "name": "FT-JCOS FIDO Fingerprint Card" + }, + "8caf7e7b-6c8b-46a9-b36b-5d04740d7463": { + "name": "cryptovision ePasslet Suite FIDO Authenticator" + }, + "8d1b1fcb-3c76-49a9-9129-5515b346aa02": { + "name": "IDEMIA ID-ONE Card" + }, + "8d4378b0-725d-4432-b3c2-01fcdaf46286": { + "name": "VeridiumID Passkey Android SDK" + }, + "8da0e4dc-164b-454e-972e-88f362b23d59": { + "name": "CardOS FIDO2 Token" + }, + "8eec9bf9-486c-46da-9a67-1fbb4f66b9ed": { + "name": "HID Crescendo 4000 FIPS" + }, + "9012593f-43e4-4461-a97a-d92777b55d74": { + "name": "VinCSS FIDO2 Fingerprint" + }, + "905b4cb4-ed6f-4da9-92fc-45e0d4e9b5c7": { + "name": "YubiKey 5 FIPS Series (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "90636e1f-ef82-43bf-bdcf-5255f139d12f": { + "name": "YubiKey Bio Series - Multi-protocol Edition" + }, + "912435d9-4a88-42f3-972d-1244b0d51420": { + "name": "SI0X FIDO CL WRIST v1.0" + }, + "91ad6b93-264b-4987-8737-3a690cad6917": { + "name": "Token Ring FIDO2 Authenticator" + }, + "930b0c03-ef46-4ac4-935c-538dccd1fcdb": { + "name": "Chipwon Clife Key" + }, + "931327dd-c89b-406c-a81e-ed7058ef36c6": { + "name": "Swissbit iShield Key FIDO2" + }, + "95442b2e-f15e-4def-b270-efb106facb4e": { + "name": "eWBM eFA310 FIDO2 Authenticator" + }, + "95e4d58c-056e-4a65-866d-f5a69659e880": { + "name": "TruU Windows Authenticator" + }, + "970c8d9c-19d2-46af-aa32-3f448db49e35": { + "name": "WinMagic FIDO Eazy - TPM" + }, + "973446ca-e21c-9a9b-99f5-9b985a67af0f": { + "name": "ACS FIDO Authenticator Card" + }, + "97e6a830-c952-4740-95fc-7c78dc97ce47": { + "name": "YubiKey Bio Series - Multi-protocol Edition (Enterprise Profile)" + }, + "9806a2c8-c0da-478e-b4ca-620005d34182": { + "name": "YubiKey Bio Multi-protocol Edition (Consumer Profile) 1VDJSN-2", + "icon_light": "7db3534fd5258565.svg" + }, + "9876631b-d4a0-427f-5773-0ec71c9e0279": { + "name": "Somu Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "9955a1cd-564c-d388-ad68-9878a27be9f1": { + "name": "StarSign Chase FIDO Card" + }, + "998f358b-2dd2-4cbe-a43a-e8107438dfb3": { + "name": "OnlyKey Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "99bf4610-ec26-4252-b31f-7380ccd59db5": { + "name": "ZTPass SmartAuth" + }, + "99ed6c29-4573-4847-816d-78ad8f1c75ef": { + "name": "VeroCard FIDO2 Authenticator" + }, + "9a272558-5cfa-4424-be37-65509677b77d": { + "name": "SECORA ID Key S USB by Infineon Consumer Edition" + }, + "9a3f2abd-a73d-439c-9ee7-1b53a857eaa7": { + "name": "YubiKey 5 Series with NFC Enhanced PIN (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "9addb28c-b46f-4402-808f-019651441ff3": { + "name": "KeePassPasskey", + "icon_light": "7fd2cfb58273936e.svg", + "icon_dark": "a8a6898e204a3630.svg" + }, + "9c835346-796b-4c27-8898-d6032f515cc5": { + "name": "Cryptnox FIDO2" + }, + "9d3df6ba-282f-11ed-a261-0242ac120002": { + "name": "Arculus FIDO2/U2F Key Card" + }, + "9dd8d593-2213-438a-97f8-d6b813d51c27": { + "name": "YubiKey Bio Fido Edition (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "9ddd1817-af5a-4672-a2b9-3e3dd95000a9": { + "name": "Windows Hello", + "icon_light": "e63a433d41e3bbd1.svg" + }, + "9e66c661-e428-452a-a8fb-51f7ed088acf": { + "name": "YubiKey 5 FIPS Series with Lightning (RC Preview)" + }, + "9eb7eabc-9db5-49a1-b6c3-555a802093f4": { + "name": "YubiKey 5 Series with NFC KVZR57", + "icon_light": "7db3534fd5258565.svg" + }, + "9eb85bb6-9625-4a72-815d-0487830ccab2": { + "name": "Ensurity AUTH BioPro Desktop" + }, + "9f0d8150-baa5-4c00-9299-ad62c8bb4e87": { + "name": "GoTrust Idem Card" + }, + "9f77e279-a6e2-4d58-b700-31e5943c6a98": { + "name": "Hyper FIDO Pro" + }, + "9f8a3b2c-1d4e-4f6a-8b0c-2e1d3c4b5a69": { + "name": "U2 Secured", + "icon_light": "a5a686d92796b3ff.svg" + }, + "9ff4cc65-6154-4fff-ba09-9e2af7882ad2": { + "name": "Security Key NFC by Yubico - Enterprise Edition (Enterprise Profile)" + }, + "a02140b7-0cbd-42e1-a9b5-a39da2545114": { + "name": "Feitian BioPass FIDO2 Plus (Enterprise Profile)" + }, + "a02167b9-ae71-4ac7-9a07-06432ebb6f1c": { + "name": "YubiKey 5 Series with Lightning" + }, + "a10c6dd9-465e-4226-8198-c7c44b91c555": { + "name": "Kaspersky Password Manager", + "icon_light": "7f0646d4fff1e946.svg" + }, + "a11a5faa-9f32-4b8c-8c5d-2f7d13e8c942": { + "name": "AliasVault", + "icon_light": "c7b0f8dd95f195cf.svg" + }, + "a1f52be5-dfab-4364-b51c-2bd496b14a56": { + "name": "OCTATCO EzFinger2 FIDO2 AUTHENTICATOR" + }, + "a25342c0-3cdc-4414-8e46-f4807fca511c": { + "name": "YubiKey 5 Series with NFC" + }, + "a3975549-b191-fd67-b8fb-017e2917fdb3": { + "name": "Excelsecu eSecu FIDO2 NFC Security Key" + }, + "a4a2d88e-9796-4356-9164-e2a5a8bd019c": { + "name": "Avast Password Manager", + "icon_light": "b8c6b04b104706c9.svg" + }, + "a4e9fc6d-4cbe-4758-b8ba-37598bb5bbaa": { + "name": "Security Key NFC by Yubico" + }, + "a6c5f5d8-2ad0-48b6-8257-e502c8970931": { + "name": "eToken FIDO NFC Enterprise" + }, + "a7fc3f84-86a3-4da4-a3d7-eb6485a066d8": { + "name": "NEOWAVE Badgeo FIDO2 (CTAP 2.1)" + }, + "aa79f476-ea00-417e-9628-1e8365123922": { + "name": "HID Crescendo 4000 FIDO" + }, + "ab32f0c6-2239-afbb-c470-d2ef4e254db6": { + "name": "TEST (DUMMY RECORD)" + }, + "ab32f0c6-2239-afbb-c470-d2ef4e254db7": { + "name": "TOKEN2 FIDO2 Security Key" + }, + "ab7d1767-3fa0-4388-b6c4-feef7a844809": { + "name": "Enterprise Security Key Series with NFC (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "ad08c78a-4e41-49b9-86a2-ac15b06899e2": { + "name": "YubiKey Bio Series - FIDO Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "adce0002-35bc-c60a-648b-0b25f1f05503": { + "name": "Chrome on Mac", + "icon_light": "53eaed3308753caf.svg" + }, + "add92433-0d69-4026-8166-29b25bce64e9": { + "name": "YubiKey Bio Fido Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "aeb6569c-f8fb-4950-ac60-24ca2bbe2e52": { + "name": "HID Crescendo C2300" + }, + "b113a455-cfb6-4c17-8cba-cd952feb7d48": { + "name": "eToken FIDO NFC" + }, + "b12eac35-586c-4809-a4b1-d81af6c305cf": { + "name": "Deepnet SafeKey/Classic (NFC)" + }, + "b267239b-954f-4041-a01b-ee4f33c145b6": { + "name": "authenton1 - CTAP2.1" + }, + "b2c1a50b-dad8-4dc7-ba4d-0ce9597904bc": { + "name": "YubiKey 5 Series with NFC - Enhanced PIN (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "b3315166-f36c-b05f-fea8-66a3dfdad171": { + "name": "Ledger Nano Gen5 FIDO2 Authenticator" + }, + "b35a26b2-8f6e-4697-ab1d-d44db4da28c6": { + "name": "Zoho Vault", + "icon_light": "72a52980cf2b1ed9.svg" + }, + "b415094c-49d3-4c8b-b3fe-7d0ad28a6bc4": { + "name": "ZTPass SmartAuth" + }, + "b50d5e0a-7f81-4959-9b12-f45407407503": { + "name": "IDPrime 3940 FIDO" + }, + "b5397666-4885-aa6b-cebf-e52262a439a2": { + "name": "Chromium Browser" + }, + "b68c4b8d-65cb-42ae-b4f6-8606dfba3c22": { + "name": "IDEMIA SOLVO Fly 80 R3 FIDO Card for j" + }, + "b6ede29c-3772-412c-8a78-539c1f4c62d2": { + "name": "Feitian BioPass FIDO2 Plus Authenticator" + }, + "b78a0a55-6ef8-d246-a042-ba0f6d55050c": { + "name": "LastPass", + "icon_light": "7d860a7c62be8a03.svg", + "icon_dark": "8f995c717fd11cf3.svg" + }, + "b7d3f68e-88a6-471e-9ecf-2df26d041ede": { + "name": "Security Key NFC by Yubico", + "icon_light": "7db3534fd5258565.svg" + }, + "b84e4048-15dc-4dd0-8640-f4f60813c8af": { + "name": "NordPass", + "icon_light": "2d20b2b69c1bdff8.svg", + "icon_dark": "55ed42788d41383d.svg" + }, + "b90e7dc1-316e-4fee-a25a-56a666a670fe": { + "name": "YubiKey 5 Series with Lightning (Enterprise Profile)" + }, + "b92c3f9a-c014-4056-887f-140a2501163b": { + "name": "Security Key by Yubico" + }, + "b93fd961-f2e6-462f-b122-82002247de78": { + "name": "Android Authenticator" + }, + "b9f6b7b6-f929-4189-bca9-dd951240c132": { + "name": "Deepnet SafeKey/Classic (USB)" + }, + "ba0a9266-40d8-4048-9786-d710b5474752": { + "name": "YubiKey Bio Multi-protocol Edition (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "ba76a271-6eb6-4171-874d-b6428dbe3437": { + "name": "ATKey.ProS" + }, + "ba86dc56-635f-4141-aef6-00227b1b9af6": { + "name": "TruU Windows Authenticator" + }, + "bada5566-a7aa-401f-bd96-45619a55120d": { + "name": "1Password", + "icon_light": "c8448a372019a31d.svg", + "icon_dark": "3c30e5f535168e89.svg" + }, + "bb405265-40cf-4115-93e5-a332c1968d8c": { + "name": "ID-One Card" + }, + "bb66c294-de08-47e4-b7aa-d12c2cd3fb20": { + "name": "Mettlesemi Vishwaas Hawk Authenticator using FIDO2" + }, + "bb878d7b-cf54-4784-b390-357030497043": { + "name": "TruU FIDO2 Authenticator" + }, + "bbf4b6a7-679d-f6fc-c4f2-8ac0ddf9015a": { + "name": "Excelsecu eSecu FIDO2 PRO Security Key" + }, + "bc2fe499-0d8e-4ffe-96f3-94a82840cf8c": { + "name": "OCTATCO EzQuant FIDO2 AUTHENTICATOR" + }, + "be727034-574a-f799-5c76-0929e0430973": { + "name": "Crayonic KeyVault K1 (USB-NFC-BLE FIDO2 Authenticator)" + }, + "bfc748bb-3429-4faa-b9f9-7cfa9f3b76d0": { + "name": "iPasswords", + "icon_light": "7b4f712b63784561.svg" + }, + "c09b3399-4a3d-306c-7bdc-967fef47241f": { + "name": "Giesecke+Devrient StarSign FIDO Card 2.1" + }, + "c1288a5c-d66b-495c-a68f-4e81f9ec5b53": { + "name": "Deepnet SafeKey/Classic (FP) XF" + }, + "c1f9a0bc-1dd2-404a-b27f-8e29047a43fd": { + "name": "YubiKey 5 FIPS Series with NFC" + }, + "c3479970-e58a-4f70-836f-853bf42fb063": { + "name": "YubiKey 5 Series with Lightning (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "c3f47802-de73-4dfc-ba22-671fe3304f90": { + "name": "eToken Fusion NFC PIV Enterprise" + }, + "c4ddaf11-3032-4e77-b3b9-3a340369b9ad": { + "name": "HID Crescendo Fusion" + }, + "c5703116-972b-4851-a3e7-ae1259843399": { + "name": "NEOWAVE Badgeo FIDO2" + }, + "c5ef55ff-ad9a-4b9f-b580-adebafe026d0": { + "name": "YubiKey 5 Series with Lightning" + }, + "c611b55c-77b2-4527-8082-590e931b2f08": { + "name": "GoTrust Idem Key " + }, + "c62100de-759b-4bf8-b22b-63b3e3a80401": { + "name": "Token Ring 3 FIDO2 Authenticator" + }, + "c80dbd9a-533f-4a17-b941-1a2f1c7cedff": { + "name": "HID Crescendo C3000" + }, + "c89674e3-a765-4b07-888a-7c086fbdf04b": { + "name": "StarSign FIDO Card" + }, + "c89e6a38-6c00-5426-5aa5-c9cbf48f0382": { + "name": "ACS FIDO Authenticator NFC" + }, + "c9cadfc9-89a9-489e-a25a-c7e86a4d5f15": { + "name": "Burp Suite Navigation Recorder", + "icon_light": "851ebd6098a28f3a.svg" + }, + "ca4cff1b-5a81-4404-8194-59aabcf1660b": { + "name": "IDPrime 3930 FIDO" + }, + "ca87cb70-4c1b-4579-a8e8-4efdd7c007e0": { + "name": "FIDO Alliance TruU Sample FIDO2 Authenticator" + }, + "cb4f796c-a20a-af9e-d639-213c1ec247f3": { + "name": "ACS PocketKey+ Bio" + }, + "cb69481e-8ff7-4039-93ec-0a2729a154a8": { + "name": "YubiKey 5 Series" + }, + "cb6f6666-38ea-4873-9161-ff456a82d316": { + "name": "iPass Secure Auth", + "icon_light": "b8db2a5d142953ed.svg", + "icon_dark": "5bca10e7f5aebe1d.svg" + }, + "cc45f64e-52a2-451b-831a-4edd8022a202": { + "name": "ToothPic Passkey Provider", + "icon_light": "3931ecb62e3b6f2a.svg", + "icon_dark": "a22945d6b8b2c855.svg" + }, + "cd69adb5-3c7a-deb9-3177-6800ea6cb72a": { + "name": "Thales PIN Android SDK", + "icon_light": "5cacab8124984715.svg", + "icon_dark": "fe2583b9176a3347.svg" + }, + "cdbdaea2-c415-5073-50f7-c04e968640b6": { + "name": "Excelsecu eSecu FIDO2 Security Key" + }, + "ce6bf97f-9f69-4ba7-9032-97adc6ca5cf1": { + "name": "YubiKey 5 FIPS Series with NFC (RC Preview)" + }, + "cfcb13a2-244f-4b36-9077-82b79d6a7de7": { + "name": "USB/NFC Passcode Authenticator" + }, + "d2717a32-9851-48a8-9961-b264c97a411a": { + "name": "Fenko Vault", + "icon_light": "33d59618e594bb49.svg" + }, + "d2fbd093-ee62-488d-9dad-1e36389f8826": { + "name": "YubiKey 5 FIPS Series (RC Preview)" + }, + "d3452668-01fd-4c12-926c-83a4204853aa": { + "name": "Microsoft Password Manager", + "icon_light": "db8f0d82e2ffc1a4.svg" + }, + "d350af52-0351-4ba2-acd3-dfeeadc3f764": { + "name": "pwSafe", + "icon_light": "986d1b758c1c0666.svg" + }, + "d384db22-4d50-ebde-2eac-5765cf1e2a44": { + "name": "Excelsecu eSecu FIDO2 Fingerprint Security Key" + }, + "d41f5a69-b817-4144-a13c-9ebd6d9254d6": { + "name": "ATKey.Card CTAP2.0" + }, + "d49b2120-b865-4191-8cea-be84a52b0485": { + "name": "Heimlane Vault", + "icon_light": "5301484de70d13e2.svg" + }, + "d548826e-79b4-db40-a3d8-11116f7e8349": { + "name": "Bitwarden", + "icon_light": "cc62b8c5575a65ae.svg" + }, + "d61d3b87-3e7c-4aea-9c50-441c371903ad": { + "name": "KeyVault Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "d716019a-9f4e-4041-9750-17c78f8ae81a": { + "name": "eToken Fusion BIO" + }, + "d7781e5d-e353-46aa-afe2-3ca49f13332a": { + "name": "YubiKey 5 Series with NFC", + "icon_light": "7db3534fd5258565.svg" + }, + "d7a423ad-3e19-4492-9200-78137dccc136": { + "name": "VivoKey Apex FIDO2" + }, + "d821a7d4-e97c-4cb6-bd82-4237731fd4be": { + "name": "Hyper FIDO Bio Security Key" + }, + "d8522d9f-575b-4866-88a9-ba99fa02f35b": { + "name": "YubiKey Bio Series - FIDO Edition" + }, + "d91c5288-0ef0-49b7-b8ae-21ca0aa6b3f3": { + "name": "KEY-ID FIDO2 Authenticator" + }, + "d94a29d9-52dd-4247-9c2d-8b818b610389": { + "name": "VeriMark Guard Fingerprint Key" + }, + "d9be9d39-e6a6-4c28-a581-32b044d986e4": { + "name": "Sticky Password Manager", + "icon_light": "7b0a06b33cb3cd3f.svg" + }, + "da1fa263-8b25-42b6-a820-c0036f21ba7f": { + "name": "ATKey.Card NFC" + }, + "da583154-ce16-4cdf-9fe6-1dba788c0998": { + "name": "Hey Be Safe", + "icon_light": "0e2f0531497ba5d8.svg" + }, + "dc5e949d-f939-43b3-9877-a85c7186b753": { + "name": "YubiKey Bio Multi-protocol Edition (Enterprise Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "dd4ec289-e01d-41c9-bb89-70fa845d4bf2": { + "name": "iCloud Keychain (Managed)", + "icon_light": "2c4bbc32e0601d9a.svg", + "icon_dark": "e5f7c847e7bb1823.svg" + }, + "dd86a2da-86a0-4cbe-b462-4bd31f57bc6f": { + "name": "YubiKey Bio Series - FIDO Edition" + }, + "dda9aa35-aaf1-4d3c-b6db-7902fd7dbbbf": { + "name": "IDEMIA SOLVO Fly 80 R3 FIDO Card c" + }, + "de503f9c-21a4-4f76-b4b7-558eb55c6f89": { + "name": "Devolutions", + "icon_light": "80ced24b0dc2e7bf.svg" + }, + "dee49ee1-11cb-47b6-bed0-8e995e67a0fb": { + "name": "SECORA Connect SLS21 D1 FIDO 2.1 v1.0 by Infineon - Consumer Edition" + }, + "def8ab1a-9f91-44f1-a103-088d8dc7d681": { + "name": "IDEMIA SOLVO Fly 80 R3 FIDO Card e" + }, + "e1a96183-5016-4f24-b55b-e3ae23614cc6": { + "name": "ATKey.Pro CTAP2.0" + }, + "e400ef8c-711d-4692-af46-7f2cf7da23ad": { + "name": "Swissbit iShield Key 2 Enterprise" + }, + "e416201b-afeb-41ca-a03d-2281c28322aa": { + "name": "ATKey.Pro CTAP2.1" + }, + "e41b42a3-60ac-4afb-8757-a98f2d7f6c9f": { + "name": "Deepnet SafeKey/Classic (FP)" + }, + "e77e3c64-05e3-428b-8824-0cbeb04b829d": { + "name": "Security Key NFC by Yubico" + }, + "e7db2bd3-f2fe-4d71-ad78-7e7aa166cfd1": { + "name": "Avira Password Manager", + "icon_light": "8f3d2a109e86bfc7.svg" + }, + "e86addcd-7711-47e5-b42a-c18257b0bf61": { + "name": "IDCore 3121 Fido" + }, + "e8b7f4a2-c3d5-e6f7-890a-b1c2d3e4f567": { + "name": "Sherlocked", + "icon_light": "d09754c3034c4d86.svg" + }, + "ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4": { + "name": "Google Password Manager", + "icon_light": "62ef07f809c7f588.svg" + }, + "eabb46cc-e241-80bf-ae9e-96fa6d2975cf": { + "name": "TOKEN2 PIN Plus Security Key Series " + }, + "eaecdef2-1c31-5634-8639-f1cbd9c00a08": { + "name": "KeePassDX", + "icon_light": "c1cfd304e92622af.svg", + "icon_dark": "9b8cfdb7d699e942.svg" + }, + "eb3b131e-59dc-536a-d176-cb7306da10f5": { + "name": "ellipticSecure MIRkey USB Authenticator" + }, + "eb7ef748-cbe0-4b40-b8f6-07bd2d592d35": { + "name": "YubiKey 5 CCN Series with NFC (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "ec31b4cc-2acc-4b8e-9c01-bade00ccbe26": { + "name": "KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2 Authenticator" + }, + "ed042a3a-4b22-4455-bb69-a267b652ae7e": { + "name": "Security Key NFC by Yubico - Enterprise Edition", + "icon_light": "7db3534fd5258565.svg" + }, + "ee041bce-25e5-4cdb-8f86-897fd6418464": { + "name": "Feitian ePass FIDO2-NFC Authenticator" + }, + "ee7fa1e0-9539-432f-bd43-9c2fc6d4f311": { + "name": "VeriMark NFC+ USB-C Security Key" + }, + "ee882879-721c-4913-9775-3dfcce97072a": { + "name": "YubiKey 5 Series" + }, + "efb96b10-a9ee-4b6c-a4a9-d32125ccd4a4": { + "name": "Safenet eToken FIDO" + }, + "f2145e86-211e-4931-b874-e22bba7d01cc": { + "name": "ID-One Key" + }, + "f3809540-7f14-49c1-a8b3-8f813b225541": { + "name": "Enpass", + "icon_light": "c98f30b9093e282e.svg", + "icon_dark": "a547d13b2f7bee29.svg" + }, + "f4c63eff-d26c-4248-801c-3736c7eaa93a": { + "name": "FIDO KeyPass S3" + }, + "f4ce5fc0-57d3-46f5-a736-efb7d5bc63b5": { + "name": "YubiKey 5 Series with NFC (Consumer Profile)", + "icon_light": "7db3534fd5258565.svg" + }, + "f56f58b3-d711-4afc-ba7d-6ac05f88cb19": { + "name": "WinMagic FIDO Eazy - Phone" + }, + "f573f209-b7fb-b261-671a-d7cf624cc812": { + "name": "Excelsecu eSecu FIDO2 PRO+ Security Key" + }, + "f7c558a0-f465-11e8-b568-0800200c9a66": { + "name": "KONAI Secp256R1 FIDO2 Conformance Testing CTAP2 Authenticator" + }, + "f8a011f3-8c0a-4d15-8006-17111f9edc7d": { + "name": "Security Key by Yubico" + }, + "f8d5c4e9-e539-4c06-8662-ec2a4155a555": { + "name": "StarSign Key Fob" + }, + "fa2b99dc-9e39-4257-8f92-4a30d23c4118": { + "name": "YubiKey 5 Series with NFC" + }, + "fa37f553-f9b6-4adb-ac53-8bbb57ebdf0d": { + "name": "Norton Password Manager", + "icon_light": "1daa712dea9ae46e.svg" + }, + "fbefdf68-fe86-0106-213e-4d5fa24cbe2e": { + "name": "Excelsecu eSecu FIDO2 NFC Security Key" + }, + "fbfc3007-154e-4ecc-8c0b-6e020557d7bd": { + "name": "Apple Passwords", + "icon_light": "9d2487ab5b1de66c.svg" + }, + "fc5ca237-69a0-4f3c-afe4-1ebc66def6df": { + "name": "Clife Key 2" + }, + "fcb1bcb4-f370-078c-6993-bc24d0ae3fbe": { + "name": "Ledger Nano X FIDO2 Authenticator" + }, + "fcc0118f-cd45-435b-8da1-9782b2da0715": { + "name": "YubiKey 5 FIPS Series with NFC", + "icon_light": "7db3534fd5258565.svg" + }, + "fdb141b2-5d84-443e-8a35-4698c205a502": { + "name": "KeePassXC", + "icon_light": "46ac2bd17caa6d0b.svg", + "icon_dark": "20285b58ca2ca438.svg" + }, + "fec067a1-f1d0-4c5e-b4c0-cc3237475461": { + "name": "KX701 SmartToken FIDO" + }, + "ff4dac45-ede8-4ec2-aced-cf66103f4335": { + "name": "YubiKey 5 Series", + "icon_light": "7db3534fd5258565.svg" + } +} diff --git a/backend/resources/files.go b/backend/resources/files.go index ecd5bd08..35df8059 100644 --- a/backend/resources/files.go +++ b/backend/resources/files.go @@ -4,5 +4,5 @@ import "embed" // Embedded file systems for the project -//go:embed email-templates/*.tmpl images default-images migrations fonts aaguids.json +//go:embed email-templates/*.tmpl images default-images migrations fonts aaguids.json aaguid-icons var FS embed.FS diff --git a/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.down.sql b/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.down.sql new file mode 100644 index 00000000..e392eefe --- /dev/null +++ b/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.down.sql @@ -0,0 +1 @@ +ALTER TABLE webauthn_credentials DROP COLUMN aaguid; diff --git a/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.up.sql b/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.up.sql new file mode 100644 index 00000000..5256ff0f --- /dev/null +++ b/backend/resources/migrations/postgres/20260916120000_webauthn_credential_icon.up.sql @@ -0,0 +1 @@ +ALTER TABLE webauthn_credentials ADD COLUMN aaguid TEXT NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; diff --git a/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.down.sql b/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.down.sql new file mode 100644 index 00000000..e392eefe --- /dev/null +++ b/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.down.sql @@ -0,0 +1 @@ +ALTER TABLE webauthn_credentials DROP COLUMN aaguid; diff --git a/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.up.sql b/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.up.sql new file mode 100644 index 00000000..5256ff0f --- /dev/null +++ b/backend/resources/migrations/sqlite/20260916120000_webauthn_credential_icon.up.sql @@ -0,0 +1 @@ +ALTER TABLE webauthn_credentials ADD COLUMN aaguid TEXT NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; diff --git a/frontend/src/lib/components/passkey-row.svelte b/frontend/src/lib/components/passkey-row.svelte index 5507159a..f4d927ca 100644 --- a/frontend/src/lib/components/passkey-row.svelte +++ b/frontend/src/lib/components/passkey-row.svelte @@ -7,6 +7,7 @@ let { icon, + providerIconUrl, onRename, onDelete, showRenameAction = true, @@ -14,18 +15,37 @@ description }: { icon: LucideIcon; + providerIconUrl?: string; onRename?: () => void; onDelete: () => void; showRenameAction?: boolean; description?: string; label?: string; } = $props(); + + // Falls back to the generic icon when the authenticator icon cannot be loaded + let iconFailed = $state(false); + + // The row is reused across passkeys and themes, so a previous failure must not hide an icon that is now a different URL + $effect(() => { + void providerIconUrl; + iconFailed = false; + }); + + const showProviderIcon = $derived(!!providerIconUrl && !iconFailed); - - {#if icon}{@const Icon = icon} - + + {#if showProviderIcon} + (iconFailed = true)} + /> + {:else if icon}{@const Icon = icon} + {/if} diff --git a/frontend/src/lib/types/passkey.type.ts b/frontend/src/lib/types/passkey.type.ts index 9c47e935..baec830d 100644 --- a/frontend/src/lib/types/passkey.type.ts +++ b/frontend/src/lib/types/passkey.type.ts @@ -2,4 +2,6 @@ export type Passkey = { id: string; name: string; createdAt: string; + aaguid: string; + hasIcon: boolean; }; diff --git a/frontend/src/lib/utils/cached-image-util.ts b/frontend/src/lib/utils/cached-image-util.ts index e547c8c7..2419bff5 100644 --- a/frontend/src/lib/utils/cached-image-util.ts +++ b/frontend/src/lib/utils/cached-image-util.ts @@ -75,6 +75,17 @@ export const cachedOidcClientLogo: CachableImage = { } }; +// Builds the URL of an authenticator icon +// Unlike the images above these are static assets that only change with a new release, so they skip the cache busting helper and rely on the backend's cache headers +export function authenticatorIconUrl(aaguid: string, light = true) { + const url = new URL( + `/api/webauthn/authenticator-icons/${encodeURIComponent(aaguid)}`, + window.location.origin + ); + if (!light) url.searchParams.set('light', 'false'); + return url.pathname + (url.search ? `?${url.searchParams.toString()}` : ''); +} + function getCachedImageUrl(url: URL) { const baseKey = normalizeUrlForKey(url); const skipCacheUntil = getSkipCacheUntil(baseKey); diff --git a/frontend/src/lib/utils/unsaved-changes-util.svelte.ts b/frontend/src/lib/utils/unsaved-changes-util.svelte.ts index 584c2a0e..ae440f0b 100644 --- a/frontend/src/lib/utils/unsaved-changes-util.svelte.ts +++ b/frontend/src/lib/utils/unsaved-changes-util.svelte.ts @@ -5,7 +5,7 @@ import { untrack } from 'svelte'; import { fromStore, type Readable } from 'svelte/store'; /** - * Registers a section of a page (e.g. a card) with the unsaved-changes bar. + * Registers a section of a page (e.g. a card) with the unsaved-changes bar. * The section is unregistered when the calling component is destroyed. */ export function trackUnsavedSection( diff --git a/frontend/src/routes/settings/account/passkey-list.svelte b/frontend/src/routes/settings/account/passkey-list.svelte index 7d2a32f4..3ccbf9d6 100644 --- a/frontend/src/routes/settings/account/passkey-list.svelte +++ b/frontend/src/routes/settings/account/passkey-list.svelte @@ -5,8 +5,10 @@ import { m } from '$lib/paraglide/messages'; import WebauthnService from '$lib/services/webauthn-service'; import type { Passkey } from '$lib/types/passkey.type'; + import { authenticatorIconUrl } from '$lib/utils/cached-image-util'; import { axiosErrorToast } from '$lib/utils/error-util'; import { LucideKeyRound } from '@lucide/svelte'; + import { mode } from 'mode-watcher'; import { toast } from 'svelte-sonner'; import RenamePasskeyModal from './rename-passkey-modal.svelte'; @@ -16,6 +18,8 @@ let passkeyToRename: Passkey | null = $state(null); + const isLightMode = $derived(mode.current === 'light'); + async function deletePasskey(passkey: Passkey) { openConfirmDialog({ title: m.delete_passkey_name({ passkeyName: passkey.name }), @@ -43,6 +47,9 @@ label={passkey.name} description={m.added_on() + ' ' + new Date(passkey.createdAt).toLocaleDateString()} icon={LucideKeyRound} + providerIconUrl={passkey.hasIcon + ? authenticatorIconUrl(passkey.aaguid, isLightMode) + : undefined} onRename={() => (passkeyToRename = passkey)} onDelete={() => deletePasskey(passkey)} /> diff --git a/frontend/src/routes/settings/admin/users/[id]/admin-passkey-list.svelte b/frontend/src/routes/settings/admin/users/[id]/admin-passkey-list.svelte index 7ab320c5..88c9681b 100644 --- a/frontend/src/routes/settings/admin/users/[id]/admin-passkey-list.svelte +++ b/frontend/src/routes/settings/admin/users/[id]/admin-passkey-list.svelte @@ -5,8 +5,10 @@ import { m } from '$lib/paraglide/messages'; import UserService from '$lib/services/user-service'; import type { Passkey } from '$lib/types/passkey.type'; + import { authenticatorIconUrl } from '$lib/utils/cached-image-util'; import { axiosErrorToast } from '$lib/utils/error-util'; import { LucideKeyRound } from '@lucide/svelte'; + import { mode } from 'mode-watcher'; import { toast } from 'svelte-sonner'; let { @@ -19,6 +21,8 @@ const userService = new UserService(); + const isLightMode = $derived(mode.current === 'light'); + async function refreshPasskeys() { passkeys = await userService.listUserPasskeys(userId); } @@ -50,6 +54,9 @@ label={passkey.name} description={m.added_on() + ' ' + new Date(passkey.createdAt).toLocaleDateString()} icon={LucideKeyRound} + providerIconUrl={passkey.hasIcon + ? authenticatorIconUrl(passkey.aaguid, isLightMode) + : undefined} showRenameAction={false} onDelete={() => deletePasskey(passkey)} /> diff --git a/scripts/update-aaguids.go b/scripts/update-aaguids.go new file mode 100644 index 00000000..f2a004bd --- /dev/null +++ b/scripts/update-aaguids.go @@ -0,0 +1,198 @@ +// Refreshes the AAGUID metadata and authenticator icons from the community AAGUID list +package main + +import ( + "bytes" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "log" + "maps" + "net/http" + "os" + "path/filepath" + "slices" + "strings" +) + +const ( + sourceURL = "https://raw.githubusercontent.com/pocket-id/passkey-aaguids/refs/heads/main/combined_aaguid.json" + metadataFile = "backend/resources/aaguids.json" + iconDir = "backend/resources/aaguid-icons" + svgDataPrefix = "data:image/svg+xml;base64," + iconFilePattern = "*.svg" + iconDigestBytes = 8 +) + +// authenticator is the subset of an upstream entry this script cares about +// The icons are data URIs rather than links, so nothing beyond the combined JSON has to be fetched +type authenticator struct { + Name string `json:"name"` + IconLight string `json:"icon_light"` + IconDark string `json:"icon_dark"` +} + +// authenticatorMetadata is the generated runtime representation of an authenticator +// Icon file names contain a 64-bit SHA-256 prefix of their decoded SVG so identical upstream icons share one asset +type authenticatorMetadata struct { + Name string `json:"name"` + IconLight string `json:"icon_light,omitempty"` + IconDark string `json:"icon_dark,omitempty"` +} + +func main() { + if err := run(); err != nil { + log.Fatalln("error:", err) + } +} + +// run writes the metadata manifest and its content-addressed icons from one upstream snapshot so their references stay consistent +func run() error { + authenticators, err := fetchAuthenticators(sourceURL) + if err != nil { + return fmt.Errorf("failed to fetch %s: %w", sourceURL, err) + } + if len(authenticators) == 0 { + return errors.New("upstream AAGUID list is empty") + } + + metadata, icons, err := buildResources(authenticators) + if err != nil { + return fmt.Errorf("failed to build authenticator resources: %w", err) + } + + if err := writeIcons(icons); err != nil { + return fmt.Errorf("failed to write icon files: %w", err) + } + + if err := writeAuthenticatorMetadata(metadata); err != nil { + return fmt.Errorf("failed to write authenticator metadata: %w", err) + } + + return nil +} + +// fetchAuthenticators downloads the upstream authenticator list keyed by AAGUID +func fetchAuthenticators(url string) (authenticators map[string]authenticator, err error) { + resp, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to get authenticator JSON: %w", err) + } + defer func() { + err = errors.Join(err, resp.Body.Close()) + }() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("expected status 200, got %s", resp.Status) + } + + if err := json.NewDecoder(resp.Body).Decode(&authenticators); err != nil { + return nil, fmt.Errorf("failed to decode JSON: %w", err) + } + + return authenticators, nil +} + +// buildResources converts upstream data URIs into metadata references and a set of unique decoded SVGs +func buildResources(authenticators map[string]authenticator) (map[string]authenticatorMetadata, map[string][]byte, error) { + metadata := make(map[string]authenticatorMetadata, len(authenticators)) + icons := make(map[string][]byte) + + // The AAGUIDs are sorted so failures are deterministic when the upstream data contains an invalid icon + for _, aaguid := range slices.Sorted(maps.Keys(authenticators)) { + a := authenticators[aaguid] + entry := authenticatorMetadata{Name: a.Name} + + // Entries without a usable light SVG retain their display names but do not reference any icon + lightName, err := addIcon(icons, a.IconLight) + if err != nil { + return nil, nil, fmt.Errorf("failed to process light SVG for %s: %w", aaguid, err) + } + if lightName == "" { + metadata[aaguid] = entry + continue + } + entry.IconLight = lightName + + // A missing or identical dark icon falls back to the light asset at runtime + darkName, err := addIcon(icons, a.IconDark) + if err != nil { + return nil, nil, fmt.Errorf("failed to process dark SVG for %s: %w", aaguid, err) + } + if darkName != "" && darkName != lightName { + entry.IconDark = darkName + } + + metadata[aaguid] = entry + } + + return metadata, icons, nil +} + +// addIcon decodes one SVG data URI and returns the content-addressed file name stored in icons +func addIcon(icons map[string][]byte, dataURI string) (string, error) { + payload, ok := strings.CutPrefix(dataURI, svgDataPrefix) + if !ok { + return "", nil + } + + svg, err := base64.StdEncoding.DecodeString(payload) + if err != nil { + return "", fmt.Errorf("failed to decode base64: %w", err) + } + + digest := sha256.Sum256(svg) + name := fmt.Sprintf("%x.svg", digest[:iconDigestBytes]) + if existing, exists := icons[name]; exists && !bytes.Equal(existing, svg) { + return "", fmt.Errorf("SHA-256 prefix collision for %s", name) + } + icons[name] = svg + + return name, nil +} + +// writeIcons replaces the icon directory contents so assets dropped upstream do not linger +func writeIcons(icons map[string][]byte) error { + if err := os.MkdirAll(iconDir, 0o755); err != nil { + return fmt.Errorf("failed to create authenticator icons directory: %w", err) + } + + existing, err := filepath.Glob(filepath.Join(iconDir, iconFilePattern)) + if err != nil { + return fmt.Errorf("error gathering existing SVGs: %w", err) + } + for _, path := range existing { + if err := os.Remove(path); err != nil { + return fmt.Errorf("error clearing existing SVG: %w", err) + } + } + + for _, name := range slices.Sorted(maps.Keys(icons)) { + if err := os.WriteFile(filepath.Join(iconDir, name), icons[name], 0o644); err != nil { + return fmt.Errorf("failed to write SVG %s: %w", name, err) + } + } + + return nil +} + +// writeAuthenticatorMetadata writes the AAGUID manifest consumed by the backend +func writeAuthenticatorMetadata(metadata map[string]authenticatorMetadata) (err error) { + if err := os.MkdirAll(filepath.Dir(metadataFile), 0o755); err != nil { + return fmt.Errorf("failed to create authenticator metadata directory: %w", err) + } + + file, err := os.Create(metadataFile) + if err != nil { + return fmt.Errorf("failed to create authenticator metadata file: %w", err) + } + defer func() { + err = errors.Join(err, file.Close()) + }() + + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + return encoder.Encode(metadata) +} diff --git a/tests/specs/cli.spec.ts b/tests/specs/cli.spec.ts index 5cfcce30..e863e785 100644 --- a/tests/specs/cli.spec.ts +++ b/tests/specs/cli.spec.ts @@ -131,6 +131,11 @@ function compareExports(dir1: string, dir2: string): void { session.extensions ??= '{}'; } + // Legacy exports gain the zero AAGUID when migrated to the current schema + for (const credential of expectedData.tables.webauthn_credentials) { + credential.aaguid ??= '00000000-0000-0000-0000-000000000000'; + } + // Check special fields validateSpecialFields(actualData);