pub const AAGUID_NAME_YUBIKEY_5_SERIES: &str = "YubiKey 5 Series";
pub const AAGUID_NAME_YUBIKEY_5_NFC: &str = "YubiKey 5 Series with NFC";
pub const AAGUID_NAME_YUBIKEY_5C: &str = "YubiKey 5 Series with Lightning";
pub const AAGUID_NAME_YUBIKEY_5_FIPS: &str = "YubiKey 5 FIPS Series";
pub const AAGUID_NAME_YUBIKEY_5_FIPS_NFC: &str = "YubiKey 5 FIPS Series with NFC";
pub const AAGUID_NAME_YUBIKEY_BIO: &str = "YubiKey Bio Series - FIDO Edition";
pub const AAGUID_NAME_SECURITY_KEY_YUBICO: &str = "Security Key by Yubico";
pub const AAGUID_NAME_SECURITY_KEY_YUBICO_NFC: &str = "Security Key NFC by Yubico";
pub const AAGUID_NAME_FEITIAN_EPASS_FIDO2: &str = "Feitian ePass FIDO2 Authenticator";
pub const AAGUID_NAME_FEITIAN_EPASS_FIDO2_NFC: &str = "Feitian ePass FIDO2-NFC Authenticator";
pub const AAGUID_NAME_FEITIAN_BIOPASS_PRO: &str = "Feitian BioPass FIDO2 Pro Authenticator";
pub const AAGUID_NAME_SOLO_SECP256R1: &str = "SoloKeys Solo Secp256R1 FIDO2 Authenticator";
pub const AAGUID_NAME_SOLO_TAP: &str = "SoloKeys Solo Tap Secp256R1 FIDO2 Authenticator";
pub const AAGUID_NAME_NITROKEY_3: &str = "Nitrokey 3 AM";
pub const AAGUID_NAME_GOOGLE_TITAN_V2: &str = "Google Titan Security Key v2";
pub const AAGUID_NAME_APPLE_ICLOUD_KEYCHAIN: &str = "Apple iCloud Keychain (Managed)";
pub const AAGUID_NAME_APPLE_PASSWORDS: &str = "Apple Passwords";
pub const AAGUID_NAME_GOOGLE_PASSWORD_MANAGER: &str = "Google Password Manager";
pub const AAGUID_NAME_CHROME_ON_MAC: &str = "Chrome on Mac";
pub const AAGUID_NAME_WINDOWS_HELLO_HARDWARE: &str = "Windows Hello Hardware Authenticator";
pub const AAGUID_NAME_WINDOWS_HELLO_SOFTWARE: &str = "Windows Hello Software Authenticator";
pub const AAGUID_NAME_WINDOWS_HELLO_VBS: &str = "Windows Hello VBS Hardware Authenticator";
pub const AAGUID_NAME_ONEPASSWORD: &str = "1Password";
pub const AAGUID_NAME_BITWARDEN: &str = "Bitwarden";
pub const AAGUID_NAME_DASHLANE: &str = "Dashlane";
pub const AAGUID_NAME_KEEPER: &str = "Keeper";
pub const AAGUID_NAME_KEEPASSXC: &str = "KeePassXC";
pub const AAGUID_NAME_SAMSUNG_PASS: &str = "Samsung Pass";
const KNOWN_AAGUIDS: &[([u8; 16], &str)] = &[
(
uuid("cb69481e-8ff7-4039-93ec-0a2729a154a8"),
AAGUID_NAME_YUBIKEY_5_SERIES,
),
(
uuid("fa2b99dc-9e39-4257-8f92-4a30d23c4118"),
AAGUID_NAME_YUBIKEY_5_NFC,
),
(
uuid("a02167b9-ae71-4ac7-9a07-06432ebb6f1c"),
AAGUID_NAME_YUBIKEY_5C,
),
(
uuid("57f7de54-c807-4eab-b1c6-1c9be7984e92"),
AAGUID_NAME_YUBIKEY_5_FIPS,
),
(
uuid("c1f9a0bc-1dd2-404a-b27f-8e29047a43fd"),
AAGUID_NAME_YUBIKEY_5_FIPS_NFC,
),
(
uuid("d8522d9f-575b-4866-88a9-ba99fa02f35b"),
AAGUID_NAME_YUBIKEY_BIO,
),
(
uuid("f8a011f3-8c0a-4d15-8006-17111f9edc7d"),
AAGUID_NAME_SECURITY_KEY_YUBICO,
),
(
uuid("b7d3f68e-88a6-471e-9ecf-2df26d041ede"),
AAGUID_NAME_SECURITY_KEY_YUBICO_NFC,
),
(
uuid("833b721a-ff5f-4d00-bb2e-bdda3ec01e29"),
AAGUID_NAME_FEITIAN_EPASS_FIDO2,
),
(
uuid("ee041bce-25e5-4cdb-8f86-897fd6418464"),
AAGUID_NAME_FEITIAN_EPASS_FIDO2_NFC,
),
(
uuid("4c0cf95d-2f40-43b5-ba42-4c83a11c04ba"),
AAGUID_NAME_FEITIAN_BIOPASS_PRO,
),
(
uuid("8876631b-d4a0-427f-5773-0ec71c9e0279"),
AAGUID_NAME_SOLO_SECP256R1,
),
(
uuid("8976631b-d4a0-427f-5773-0ec71c9e0279"),
AAGUID_NAME_SOLO_TAP,
),
(
uuid("2cd2f727-f6ca-44da-8f48-5c2e5da000a2"),
AAGUID_NAME_NITROKEY_3,
),
(
uuid("42b4fb4a-2866-43b2-9bf7-6c6669c2e5d3"),
AAGUID_NAME_GOOGLE_TITAN_V2,
),
(
uuid("dd4ec289-e01d-41c9-bb89-70fa845d4bf2"),
AAGUID_NAME_APPLE_ICLOUD_KEYCHAIN,
),
(
uuid("fbfc3007-154e-4ecc-8c0b-6e020557d7bd"),
AAGUID_NAME_APPLE_PASSWORDS,
),
(
uuid("ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4"),
AAGUID_NAME_GOOGLE_PASSWORD_MANAGER,
),
(
uuid("adce0002-35bc-c60a-648b-0b25f1f05503"),
AAGUID_NAME_CHROME_ON_MAC,
),
(
uuid("08987058-cadc-4b81-b6e1-30de50dcbe96"),
AAGUID_NAME_WINDOWS_HELLO_HARDWARE,
),
(
uuid("9ddd1817-af5a-4672-a2b9-3e3dd95000a9"),
AAGUID_NAME_WINDOWS_HELLO_SOFTWARE,
),
(
uuid("6028b017-b1d4-4c02-b4b3-afcdafc96bb2"),
AAGUID_NAME_WINDOWS_HELLO_VBS,
),
(
uuid("bada5566-a7aa-401f-bd96-45619a55120d"),
AAGUID_NAME_ONEPASSWORD,
),
(
uuid("d548826e-79b4-db40-a3d8-11116f7e8349"),
AAGUID_NAME_BITWARDEN,
),
(
uuid("531126d6-e717-415c-9320-3d9aa6981239"),
AAGUID_NAME_DASHLANE,
),
(
uuid("0ea242b4-43c4-4a1b-8b17-dd6d0b6baec6"),
AAGUID_NAME_KEEPER,
),
(
uuid("fdb141b2-5d84-443e-8a35-4698c205a502"),
AAGUID_NAME_KEEPASSXC,
),
(
uuid("53414d53-554e-4700-0000-000000000000"),
AAGUID_NAME_SAMSUNG_PASS,
),
];
#[allow(clippy::panic, clippy::indexing_slicing)]
const fn uuid(s: &str) -> [u8; 16] {
const fn nibble(c: u8) -> u8 {
match c {
b'0'..=b'9' => c - b'0',
b'a'..=b'f' => c - b'a' + 10,
b'A'..=b'F' => c - b'A' + 10,
_ => panic!("invalid hex digit in AAGUID constant"),
}
}
let bytes = s.as_bytes();
let mut out = [0u8; 16];
let mut out_i = 0;
let mut i = 0;
while i < bytes.len() {
let c = bytes[i];
if c == b'-' {
i += 1;
continue;
}
if out_i >= 16 || i + 1 >= bytes.len() {
panic!("AAGUID constant is not a 16-byte UUID");
}
out[out_i] = (nibble(c) << 4) | nibble(bytes[i + 1]);
out_i += 1;
i += 2;
}
if out_i != 16 {
panic!("AAGUID constant is not a 16-byte UUID");
}
out
}
pub fn known_aaguid(aaguid: &[u8; 16]) -> Option<&'static str> {
KNOWN_AAGUIDS
.iter()
.find(|(known, _)| known == aaguid)
.map(|(_, name)| *name)
}
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic
)]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn known_entries_resolve() {
let yubikey5 = uuid("cb69481e-8ff7-4039-93ec-0a2729a154a8");
assert_eq!(known_aaguid(&yubikey5), Some(AAGUID_NAME_YUBIKEY_5_SERIES));
let windows_hello = uuid("08987058-cadc-4b81-b6e1-30de50dcbe96");
assert_eq!(
known_aaguid(&windows_hello),
Some(AAGUID_NAME_WINDOWS_HELLO_HARDWARE)
);
let gpm = uuid("ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4");
assert_eq!(
known_aaguid(&gpm),
Some(AAGUID_NAME_GOOGLE_PASSWORD_MANAGER)
);
}
#[test]
fn unknown_aaguid_returns_none() {
assert_eq!(known_aaguid(&[0u8; 16]), None);
assert_eq!(known_aaguid(&[0xEE; 16]), None);
}
#[test]
fn uuid_helper_layout() {
let samsung = uuid("53414d53-554e-4700-0000-000000000000");
assert_eq!(&samsung[0..7], b"SAMSUNG");
assert_eq!(samsung[7], 0x00);
assert_eq!(&samsung[8..], &[0u8; 8]);
}
#[test]
#[should_panic(expected = "AAGUID constant is not a 16-byte UUID")]
fn uuid_rejects_odd_length_with_named_panic() {
let _ = uuid("53414d5");
}
#[test]
fn uuid_accepts_uppercase_hex() {
let lower = uuid("cb69481e-8ff7-4039-93ec-0a2729a154a8");
let upper = uuid("CB69481E-8FF7-4039-93EC-0A2729A154A8");
assert_eq!(lower, upper);
}
#[test]
#[should_panic(expected = "invalid hex digit")]
fn uuid_rejects_non_hex_digit() {
let _ = uuid("zz69481e-8ff7-4039-93ec-0a2729a154a8");
}
#[test]
#[should_panic(expected = "not a 16-byte UUID")]
fn uuid_rejects_overlong_input() {
let _ = uuid("cb69481e-8ff7-4039-93ec-0a2729a154a8ff");
}
#[test]
#[should_panic(expected = "not a 16-byte UUID")]
fn uuid_rejects_empty_input() {
let _ = uuid("");
}
}