From cf6a53615eed2b807e75a93c214c5d067b720338 Mon Sep 17 00:00:00 2001 From: "J.L.M" <57787248+JMarkstrom@users.noreply.github.com> Date: Fri, 12 Sep 2025 13:56:18 +0200 Subject: [PATCH 1/3] Revised EA cmdlet. Still requires PIN (may be SDK issue). --- .gitignore | 1 + ...EnableYubikeyFIDO2EnterpriseAttestation.cs | 49 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index f4afde3..18f5e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -364,3 +364,4 @@ FodyWeavers.xsd /.vscode/launch.json /powershellYK.psd1 /.cursorrules +/Docs/Cookbook/Set-BIO-random-PIN.ps1 diff --git a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs index d6b602a..be84e3c 100644 --- a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs +++ b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs @@ -3,7 +3,7 @@ /// Enterprise attestation (EA) allows the YubiKey to provide detailed device information /// during FIDO2 authentication, which can be useful for enterprise deployments. /// Requires a YubiKey capable of Enterprise Attestation and administrator privileges on Windows. -/// Note: Enterprise attestation cannot be disabled without resetting the FIDO2 applet. +/// Note: Enterprise attestation is only disabled when resetting the FIDO2 applet. /// /// .EXAMPLE /// Enable-YubiKeyFIDO2EnterpriseAttestation @@ -25,26 +25,23 @@ namespace powershellYK.Cmdlets.Fido { - [Cmdlet(VerbsLifecycle.Enable, "YubiKeyFIDO2EnterpriseAttestation", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)] + [Cmdlet(VerbsLifecycle.Enable, "YubiKeyFIDO2EnterpriseAttestation")] public class EnableYubikeyFIDO2CmdletEnterpriseAttestation : PSCmdlet { // Initialize processing and verify requirements protected override void BeginProcessing() { - // Connect to FIDO2 if not already authenticated - if (YubiKeyModule._fido2PIN is null) + // Connect to a YubiKey if not already connected + if (YubiKeyModule._yubikey is null) { - WriteDebug("No FIDO2 session has been authenticated, calling Connect-YubikeyFIDO2"); - var myPowersShellInstance = PowerShell.Create(RunspaceMode.CurrentRunspace).AddCommand("Connect-YubikeyFIDO2"); + WriteDebug("No YubiKey selected, calling Connect-Yubikey..."); + var myPowersShellInstance = PowerShell.Create(RunspaceMode.CurrentRunspace).AddCommand("Connect-Yubikey"); if (this.MyInvocation.BoundParameters.ContainsKey("InformationAction")) { myPowersShellInstance = myPowersShellInstance.AddParameter("InformationAction", this.MyInvocation.BoundParameters["InformationAction"]); } myPowersShellInstance.Invoke(); - if (YubiKeyModule._fido2PIN is null) - { - throw new Exception("Connect-YubikeyFIDO2 failed to connect FIDO2 application."); - } + WriteDebug($"Successfully connected"); } // Check if running as Administrator @@ -57,19 +54,39 @@ protected override void BeginProcessing() // Process the main cmdlet logic protected override void ProcessRecord() { + // Create a FIDO2 session with the YubiKey using (var fido2Session = new Fido2Session((YubiKeyDevice)YubiKeyModule._yubikey!)) { - // Set up key collector for PIN operations - fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; - fido2Session.AuthenticatorInfo.Options!.Any(v => v.Key.Contains(AuthenticatorOptions.ep)); - if (!(fido2Session.AuthenticatorInfo.Options!.Any(v => v.Key.Contains(AuthenticatorOptions.ep))) || fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.ep) == OptionValue.False) + // Check if enterprise attestation is supported + if (!fido2Session.AuthenticatorInfo.Options!.Any(v => v.Key.Contains(AuthenticatorOptions.ep))) { throw new Exception("Enterprise attestation not supported by this YubiKey."); } - if (ShouldProcess("Enterprise attestion cannot be disabled without resetting the FIDO2 applet.", "Enterprise attestion cannot be disabled without resetting the FIDO2 applet.", "Disable not possible.")) + + // Check if enterprise attestation is already enabled + if (fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.ep) == OptionValue.True) + { + WriteWarning("Enterprise attestation is already enabled on this YubiKey."); + return; + } + + // Check if PIN is required (only when alwaysUv is enabled but clientPin is not set) + bool alwaysUv = fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.alwaysUv) == OptionValue.True; + bool clientPin = fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.clientPin) == OptionValue.True; + + if (alwaysUv && !clientPin) + { + throw new Exception("Enabling Enterprise Attestation requires a PIN to be set when alwaysUv is enabled."); + } + + // Set up key collector only if PIN authentication is needed + if (clientPin) { - fido2Session.TryEnableEnterpriseAttestation(); + fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; } + + // Enable enterprise attestation if supported by the YubiKey + fido2Session.TryEnableEnterpriseAttestation(); } } } From e0fc9655ac15cff237077addc74b718d8a94dd28 Mon Sep 17 00:00:00 2001 From: "J.L.M" <57787248+JMarkstrom@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:47:30 +0200 Subject: [PATCH 2/3] Improvements to ea cmdlet --- ...EnableYubikeyFIDO2EnterpriseAttestation.cs | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs index be84e3c..4b5558c 100644 --- a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs +++ b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs @@ -1,5 +1,5 @@ /// -/// Enables enterprise attestation the YubiKey FIDO2 applet. +/// Enables enterprise attestation on the YubiKey FIDO2 applet. /// Enterprise attestation (EA) allows the YubiKey to provide detailed device information /// during FIDO2 authentication, which can be useful for enterprise deployments. /// Requires a YubiKey capable of Enterprise Attestation and administrator privileges on Windows. @@ -10,8 +10,8 @@ /// Enables enterprise attestation on the connected YubiKey /// /// .EXAMPLE -/// Enable-YubiKeyFIDO2EnterpriseAttestation -Confirm:$false -/// Enables enterprise attestation without confirmation prompt +/// Enable-YubiKeyFIDO2EnterpriseAttestation -InformationAction Continue +/// Enables enterprise attestation and displays informational messages /// // Imports @@ -31,17 +31,20 @@ public class EnableYubikeyFIDO2CmdletEnterpriseAttestation : PSCmdlet // Initialize processing and verify requirements protected override void BeginProcessing() { - // Connect to a YubiKey if not already connected - if (YubiKeyModule._yubikey is null) + // Connect to FIDO2 if not already authenticated + if (YubiKeyModule._fido2PIN is null) { - WriteDebug("No YubiKey selected, calling Connect-Yubikey..."); - var myPowersShellInstance = PowerShell.Create(RunspaceMode.CurrentRunspace).AddCommand("Connect-Yubikey"); + WriteDebug("No FIDO2 session has been authenticated, calling Connect-YubikeyFIDO2..."); + var myPowersShellInstance = PowerShell.Create(RunspaceMode.CurrentRunspace).AddCommand("Connect-YubikeyFIDO2"); if (this.MyInvocation.BoundParameters.ContainsKey("InformationAction")) { myPowersShellInstance = myPowersShellInstance.AddParameter("InformationAction", this.MyInvocation.BoundParameters["InformationAction"]); } myPowersShellInstance.Invoke(); - WriteDebug($"Successfully connected"); + if (YubiKeyModule._fido2PIN is null) + { + throw new Exception("Connect-YubikeyFIDO2 failed to connect to the FIDO2 applet!"); + } } // Check if running as Administrator @@ -66,27 +69,16 @@ protected override void ProcessRecord() // Check if enterprise attestation is already enabled if (fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.ep) == OptionValue.True) { - WriteWarning("Enterprise attestation is already enabled on this YubiKey."); + WriteInformation("Enterprise attestation is already enabled on this YubiKey.", new string[] { "FIDO2", "Info" }); return; } - // Check if PIN is required (only when alwaysUv is enabled but clientPin is not set) - bool alwaysUv = fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.alwaysUv) == OptionValue.True; - bool clientPin = fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.clientPin) == OptionValue.True; - - if (alwaysUv && !clientPin) - { - throw new Exception("Enabling Enterprise Attestation requires a PIN to be set when alwaysUv is enabled."); - } - - // Set up key collector only if PIN authentication is needed - if (clientPin) - { - fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; - } + // Set up key collector for PIN operations (required by SDK) + fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; // Enable enterprise attestation if supported by the YubiKey fido2Session.TryEnableEnterpriseAttestation(); + WriteInformation("Enterprise attestation has been successfully enabled on this YubiKey.", new string[] { "FIDO2", "Info" }); } } } From 89ee140edb4ca0f45bafd6bb11c29e949d59240b Mon Sep 17 00:00:00 2001 From: Oscar Virot Date: Sun, 26 Oct 2025 21:14:33 +0100 Subject: [PATCH 3/3] ran dotnet format on EnableYubikeyFIDO2CmdletEnterpriseAttestation --- .../FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs index 4b5558c..b5801bb 100644 --- a/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs +++ b/Module/Cmdlets/FIDO2/EnableYubikeyFIDO2EnterpriseAttestation.cs @@ -65,17 +65,17 @@ protected override void ProcessRecord() { throw new Exception("Enterprise attestation not supported by this YubiKey."); } - + // Check if enterprise attestation is already enabled if (fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.ep) == OptionValue.True) { WriteInformation("Enterprise attestation is already enabled on this YubiKey.", new string[] { "FIDO2", "Info" }); return; } - + // Set up key collector for PIN operations (required by SDK) fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; - + // Enable enterprise attestation if supported by the YubiKey fido2Session.TryEnableEnterpriseAttestation(); WriteInformation("Enterprise attestation has been successfully enabled on this YubiKey.", new string[] { "FIDO2", "Info" });