Skip to content

Commit 47874a7

Browse files
Add GetMetadata function to PivSampleCode
1 parent 1c8832f commit 47874a7

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

Yubico.YubiKey/examples/PivSampleCode/Run/PivMainMenuItem.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ public enum PivMainMenuItem
4141
BuildSelfSignedCert = 18,
4242
BuildCert = 19,
4343
RetrieveCert = 20,
44+
GetMetadata = 21,
4445

45-
CreateAttestationStatement = 21,
46-
GetAttestationCertificate = 22,
46+
CreateAttestationStatement = 22,
47+
GetAttestationCertificate = 23,
4748

48-
ResetPiv = 23,
49-
Exit = 24,
49+
ResetPiv = 24,
50+
Exit = 25,
5051
}
5152
}

Yubico.YubiKey/examples/PivSampleCode/Run/PivSampleRun.Operations.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public partial class PivSampleRun
6464
PivMainMenuItem.BuildSelfSignedCert => RunBuildSelfSignedCert(),
6565
PivMainMenuItem.BuildCert => RunBuildCert(),
6666
PivMainMenuItem.RetrieveCert => RunRetrieveCert(),
67+
PivMainMenuItem.GetMetadata => RunGetMetadata(),
6768
PivMainMenuItem.CreateAttestationStatement => RunCreateAttestationStatement(),
6869
PivMainMenuItem.GetAttestationCertificate => RunGetAttestationCert(),
6970
PivMainMenuItem.ResetPiv =>
@@ -83,6 +84,61 @@ public static bool RunUnimplementedOperation()
8384
return true;
8485
}
8586

87+
public bool RunGetMetadata()
88+
{
89+
if (_yubiKeyChosen is null)
90+
{
91+
SampleMenu.WriteMessage(MessageType.Special, 0, "You must choose a YubiKey first.");
92+
return true;
93+
}
94+
95+
try
96+
{
97+
using (var pivSession = new PivSession(_yubiKeyChosen))
98+
{
99+
_ = GetAsymmetricSlotNumber(out byte slotNumber);
100+
PivMetadata metadata = pivSession.GetMetadata(slotNumber);
101+
102+
if (metadata is null)
103+
{
104+
SampleMenu.WriteMessage(MessageType.Special, 0, $"\nNo key or certificate found in slot {GetPivSlotName(slotNumber)}.\n");
105+
return true;
106+
}
107+
108+
SampleMenu.WriteMessage(MessageType.Title, 0, "Slot: " + GetPivSlotName(slotNumber));
109+
SampleMenu.WriteMessage(MessageType.Title, 0, "Algorithm: " + metadata.Algorithm);
110+
SampleMenu.WriteMessage(MessageType.Title, 0, "Key status: " + metadata.KeyStatus);
111+
SampleMenu.WriteMessage(MessageType.Title, 0, "Pin policy: " + metadata.PinPolicy);
112+
SampleMenu.WriteMessage(MessageType.Title, 0, "Touch policy: " + metadata.TouchPolicy + "\n");
113+
}
114+
}
115+
catch (Exception e)
116+
{
117+
SampleMenu.WriteMessage(MessageType.Special, 0, $"Error getting metadata: {e.Message}");
118+
}
119+
120+
return true; // Keep the menu running
121+
}
122+
public static string GetPivSlotName(int slotNumber)
123+
{
124+
string name = (byte)slotNumber switch
125+
{
126+
0x9a => "PIV Authentication",
127+
0x9c => "Digital Signature",
128+
0x9d => "Key Management",
129+
0x9e => "Card Authentication",
130+
0xf9 => "Attestation",
131+
132+
// Handle the 20 "Retired" key management slots
133+
>= 0x82 and <= 0x95 => $"Retired Key {slotNumber - 0x82 + 1}",
134+
135+
_ => "Unknown Slot"
136+
};
137+
138+
return $"{name} ({(byte)slotNumber:X2})";
139+
}
140+
141+
86142
public bool RunChangeRetryCount()
87143
{
88144
if (!GetNewRetryCounts(out byte newRetryCountPin, out byte newRetryCountPuk))

0 commit comments

Comments
 (0)