From a9e5d91bfe421cedfc1fa029c19a978c0718071f Mon Sep 17 00:00:00 2001 From: Jonas Markstrom Date: Wed, 8 Jan 2025 09:26:19 +0100 Subject: [PATCH 1/3] 1. Fixed help message on RemoveYubiKeyPIVKey.cs. 2. Renamed attributes listing FIDO2 credentials 3. Added CredentialID to listing --- .../Fido/GetYubikeyFIDO2Credentials.cs | 20 +++++++++++++------ Module/Cmdlets/PIV/RemoveYubikeyPIVKey.cs | 2 +- Module/types/FIDO2-Credentials.cs | 6 +++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs b/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs index d58eaa3..43761a8 100644 --- a/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs +++ b/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs @@ -37,22 +37,30 @@ protected override void ProcessRecord() { fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; - var RelyingParties = fido2Session.EnumerateRelyingParties(); - foreach (RelyingParty RelyingParty in RelyingParties) + var relyingParties = fido2Session.EnumerateRelyingParties(); + foreach (RelyingParty relyingParty in relyingParties) { - var relayCredentials = fido2Session.EnumerateCredentialsForRelyingParty(RelyingParty); + var relayCredentials = fido2Session.EnumerateCredentialsForRelyingParty(relyingParty); foreach (CredentialUserInfo user in relayCredentials) { + byte[] credentialIdBytes = user.CredentialId.Id.ToArray(); + + string credentialIdBase64 = Convert.ToBase64String(credentialIdBytes); + Credentials credentials = new Credentials { - Site = RelyingParty.Id, - Name = user.User.Name, - DisplayName = user.User.DisplayName, + CredentialID = credentialIdBase64, // TODO: too long for display purposes? + RPId = relyingParty.Id, + UserName = user.User.Name, + DisplayName = user.User.DisplayName }; + WriteObject(credentials); } } } } + + } } \ No newline at end of file diff --git a/Module/Cmdlets/PIV/RemoveYubikeyPIVKey.cs b/Module/Cmdlets/PIV/RemoveYubikeyPIVKey.cs index c30f51f..c215f54 100644 --- a/Module/Cmdlets/PIV/RemoveYubikeyPIVKey.cs +++ b/Module/Cmdlets/PIV/RemoveYubikeyPIVKey.cs @@ -11,7 +11,7 @@ public class RemoveYubiKeyPIVKeyCmdlet : Cmdlet { [ArgumentCompletions("\"PIV Authentication\"", "\"Digital Signature\"", "\"Key Management\"", "\"Card Authentication\"", "0x9a", "0x9c", "0x9d", "0x9e")] [ValidateYubikeyPIVSlot(DontAllowAttestion = true)] - [Parameter(Mandatory = true, ValueFromPipeline = false, HelpMessage = "What slot to move a key from")] + [Parameter(Mandatory = true, ValueFromPipeline = false, HelpMessage = "What slot to remove a key from")] public PIVSlot Slot { get; set; } protected override void BeginProcessing() { diff --git a/Module/types/FIDO2-Credentials.cs b/Module/types/FIDO2-Credentials.cs index f6b3aea..d99732a 100644 --- a/Module/types/FIDO2-Credentials.cs +++ b/Module/types/FIDO2-Credentials.cs @@ -8,10 +8,10 @@ namespace powershellYK.FIDO2 { public class Credentials { - public string? Site { get; set; } - public string? Name { get; set; } + public string? CredentialID { get; set; } + public string? RPId { get; set; } + public string? UserName { get; set; } public string? DisplayName { get; set; } - // public CredentialId? CredentialID { get; set; } } } From ec21d754ce10d301b0ddd0141f462f6afb30119a Mon Sep 17 00:00:00 2001 From: Oscar Virot Date: Wed, 8 Jan 2025 19:51:27 +0100 Subject: [PATCH 2/3] Rename Credentials to Credential Remove requirement of PIN for Get-YubiKeyFIDO2 Update the Type FIDO2-Credential --- ...tials.md => Get-YubikeyFIDO2Credential.md} | 6 ++-- Module/Cmdlets/Fido/ConnectYubikeyFIDO2.cs | 6 ++-- Module/Cmdlets/Fido/GetYubikeyFIDO2.cs | 15 ++++------ .../Fido/GetYubikeyFIDO2Credentials.cs | 17 ++++------- Module/powershellYK.psd1 | 2 +- Module/types/FIDO2-Credentials.cs | 29 +++++++++++++++---- 6 files changed, 42 insertions(+), 33 deletions(-) rename Docs/Commands/{Get-YubikeyFIDO2Credentials.md => Get-YubikeyFIDO2Credential.md} (89%) diff --git a/Docs/Commands/Get-YubikeyFIDO2Credentials.md b/Docs/Commands/Get-YubikeyFIDO2Credential.md similarity index 89% rename from Docs/Commands/Get-YubikeyFIDO2Credentials.md rename to Docs/Commands/Get-YubikeyFIDO2Credential.md index a0d213f..e3c885b 100644 --- a/Docs/Commands/Get-YubikeyFIDO2Credentials.md +++ b/Docs/Commands/Get-YubikeyFIDO2Credential.md @@ -5,7 +5,7 @@ online version: schema: 2.0.0 --- -# Get-YubikeyFIDO2Credentials +# Get-YubikeyFIDO2Credential ## SYNOPSIS Read the FIDO2 discoverable credentials @@ -13,7 +13,7 @@ Read the FIDO2 discoverable credentials ## SYNTAX ``` -Get-YubikeyFIDO2Credentials [] +Get-YubikeyFIDO2Credential [] ``` ## DESCRIPTION @@ -23,7 +23,7 @@ Get what FIDO2 credentials that have been saved in the Yubikey. ### Example 1 ```powershell -PS C:\> Get-YubikeyFIDO2Credentials +PS C:\> Get-YubikeyFIDO2Credential Site Name DisplayName ---- ---- ----------- diff --git a/Module/Cmdlets/Fido/ConnectYubikeyFIDO2.cs b/Module/Cmdlets/Fido/ConnectYubikeyFIDO2.cs index 6ea6b91..cfb150f 100644 --- a/Module/Cmdlets/Fido/ConnectYubikeyFIDO2.cs +++ b/Module/Cmdlets/Fido/ConnectYubikeyFIDO2.cs @@ -77,6 +77,7 @@ protected override void BeginProcessing() } // Check if Connect-YubikeyFIDO2 was called without a PIN (only possible with Yubikey that doesnt have a PIN configured) + /* if (this.MyInvocation.BoundParameters.ContainsKey("PIN") == false) { WriteWarning("FIDO2 has no PIN, please set PIN before continuing:"); @@ -88,6 +89,7 @@ protected override void BeginProcessing() } myPowersShellInstance.Invoke(); } + */ #if WINDOWS @@ -106,12 +108,12 @@ protected override void ProcessRecord() { if (fido2Session.AuthenticatorInfo.GetOptionValue(AuthenticatorOptions.clientPin) == OptionValue.False) { - WriteWarning("Client PIN is not set."); + WriteWarning("Client PIN is not set, see Set-YubiKeyFIDO2PIN."); return; } else if (fido2Session.AuthenticatorInfo.ForcePinChange == true) { - WriteWarning("YubiKey requires PIN change to continue, see Set-YubikeyFIDO2 -SetPIN."); + WriteWarning("YubiKey requires PIN change to continue, see Set-YubiKeyFIDO2PIN."); return; } if (this.MyInvocation.BoundParameters["PIN"] is not null) diff --git a/Module/Cmdlets/Fido/GetYubikeyFIDO2.cs b/Module/Cmdlets/Fido/GetYubikeyFIDO2.cs index 92b14e5..38eb894 100644 --- a/Module/Cmdlets/Fido/GetYubikeyFIDO2.cs +++ b/Module/Cmdlets/Fido/GetYubikeyFIDO2.cs @@ -13,23 +13,19 @@ public class GetYubikeyFIDO2Cmdlet : PSCmdlet { protected override void BeginProcessing() { - // If no FIDO2 PIN exists, we need to connect to the FIDO2 application - if (YubiKeyModule._fido2PIN is null) + // Get-YubiKeyFIDO2, does not require authentication, so just make sure we have a YubiKey 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 the FIDO2 applet!"); - } + WriteDebug($"Successfully connected"); } - // Check if running as Administrator if (Windows.IsRunningAsAdministrator() == false) { @@ -41,7 +37,6 @@ protected override void ProcessRecord() { using (var fido2Session = new Fido2Session((YubiKeyDevice)YubiKeyModule._yubikey!)) { - fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; AuthenticatorInfo info = fido2Session.AuthenticatorInfo; WriteObject(new Information(info)); diff --git a/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs b/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs index 46502b8..a3c5632 100644 --- a/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs +++ b/Module/Cmdlets/Fido/GetYubikeyFIDO2Credentials.cs @@ -7,7 +7,8 @@ namespace powershellYK.Cmdlets.Fido { - [Cmdlet(VerbsCommon.Get, "YubikeyFIDO2Credentials")] + [Alias("Get-YubikeyFIDO2Credentials")] + [Cmdlet(VerbsCommon.Get, "YubikeyFIDO2Credential")] public class GetYubikeyFIDO2CredentialsCommand : PSCmdlet { @@ -43,7 +44,7 @@ protected override void ProcessRecord() fido2Session.KeyCollector = YubiKeyModule._KeyCollector.YKKeyCollectorDelegate; var relyingParties = fido2Session.EnumerateRelyingParties(); - if (!RelyingParties.Any()) // Check if there are no relying parties + if (!relyingParties.Any()) // Check if there are no relying parties { WriteWarning("No credentials found on the YubiKey."); return; @@ -55,16 +56,8 @@ protected override void ProcessRecord() var relayCredentials = fido2Session.EnumerateCredentialsForRelyingParty(relyingParty); foreach (CredentialUserInfo user in relayCredentials) { - byte[] credentialIdBytes = user.CredentialId.Id.ToArray(); - string credentialIdBase64 = Convert.ToBase64String(credentialIdBytes); - Credentials credentials = new Credentials - { - CredentialID = credentialIdBase64, // TODO: too long for display purposes? - RPId = relyingParty.Id, - UserName = user.User.Name, - DisplayName = user.User.DisplayName - }; - WriteObject(credentials); + Credential credential = new Credential(RPId: relyingParty.Id, UserName: user.User.Name, DisplayName: user.User.DisplayName, CredentialID: user.CredentialId); + WriteObject(credential); } } } diff --git a/Module/powershellYK.psd1 b/Module/powershellYK.psd1 index b93f0fd..9888071 100644 --- a/Module/powershellYK.psd1 +++ b/Module/powershellYK.psd1 @@ -83,7 +83,7 @@ CmdletsToExport = @( 'Connect-YubikeyFIDO2', 'Enable-YubikeyFIDO2EnterpriseAttestation', 'Get-YubikeyFIDO2', - 'Get-YubikeyFIDO2Credentials', + 'Get-YubikeyFIDO2Credential', 'Set-YubikeyFIDO2', 'Set-YubikeyFIDO2PIN', 'Reset-YubikeyFIDO2', diff --git a/Module/types/FIDO2-Credentials.cs b/Module/types/FIDO2-Credentials.cs index 41bcc20..3141d13 100644 --- a/Module/types/FIDO2-Credentials.cs +++ b/Module/types/FIDO2-Credentials.cs @@ -4,16 +4,35 @@ using System.Management.Automation; using Yubico.YubiKey.Fido2; using Yubico.YubiKey.Fido2.Cose; +using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; namespace powershellYK.FIDO2 { - public class Credentials + public class Credential { - public string? RPId { get; set; } - public string? UserName { get; set; } - public string? DisplayName { get; set; } - public CredentialId? CredentialID { get; set; } + public string? DisplayName { get; private set; } + public string? UserName { get; private set; } + public string? RPId { get; private set; } + public string? CredID { get + { + byte[] credentialIdBytes = CredentialID.Id.ToArray(); + + string credentialIdBase64 = Convert.ToBase64String(credentialIdBytes); + return credentialIdBase64; + } + } + [Hidden] + public CredentialId CredentialID { get; private set; } [Hidden] public CoseKey? coseKey { get; set; } + + public Credential(string RPId, string? UserName, string? DisplayName, CredentialId CredentialID) + { + this.RPId = RPId; + this.UserName = UserName; + this.DisplayName = DisplayName; + this.CredentialID = CredentialID; + } } } + \ No newline at end of file From 8254da7b87880d08b490b21c11221702df874ea3 Mon Sep 17 00:00:00 2001 From: Oscar Virot Date: Wed, 8 Jan 2025 19:57:58 +0100 Subject: [PATCH 3/3] Fix formating --- Module/types/FIDO2-Credentials.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Module/types/FIDO2-Credentials.cs b/Module/types/FIDO2-Credentials.cs index 3141d13..e5bf855 100644 --- a/Module/types/FIDO2-Credentials.cs +++ b/Module/types/FIDO2-Credentials.cs @@ -13,11 +13,13 @@ public class Credential public string? DisplayName { get; private set; } public string? UserName { get; private set; } public string? RPId { get; private set; } - public string? CredID { get + public string? CredID + { + get { byte[] credentialIdBytes = CredentialID.Id.ToArray(); - string credentialIdBase64 = Convert.ToBase64String(credentialIdBytes); + string credentialIdBase64 = Convert.ToBase64String(credentialIdBytes); return credentialIdBase64; } } @@ -35,4 +37,3 @@ public Credential(string RPId, string? UserName, string? DisplayName, Credential } } } - \ No newline at end of file